* [PATCH v5 1/7] net: phy: broadcom: add bcm54xx_auxctl_read
From: Florian Fainelli @ 2016-11-02 17:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-2-git-send-email-jon.mason@broadcom.com>
On 11/02/2016 10:08 AM, Jon Mason wrote:
> Add a helper function to read the AUXCTL register for the BCM54xx. This
> mirrors the bcm54xx_auxctl_write function already present in the code.
>
> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* [PATCH v5 7/7] arm64: dts: NS2: add AMAC ethernet support
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-1-git-send-email-jon.mason@broadcom.com>
Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device
tree
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 +++++
arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 ++++++++++++
2 files changed, 17 insertions(+)
diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index 2d7872a..2e4d90d 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -56,6 +56,10 @@
};
};
+&enet {
+ status = "ok";
+};
+
&pci_phy0 {
status = "ok";
};
@@ -172,6 +176,7 @@
&mdio_mux_iproc {
mdio at 10 {
gphy0: eth-phy at 10 {
+ enet-phy-lane-swap;
reg = <0x10>;
};
};
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index d95dc40..773ed59 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -191,6 +191,18 @@
#include "ns2-clock.dtsi"
+ enet: ethernet at 61000000 {
+ compatible = "brcm,ns2-amac";
+ reg = <0x61000000 0x1000>,
+ <0x61090000 0x1000>,
+ <0x61030000 0x100>;
+ reg-names = "amac_base", "idm_base", "nicpm_base";
+ interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+ phy-handle = <&gphy0>;
+ phy-mode = "rgmii";
+ status = "disabled";
+ };
+
dma0: dma at 61360000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x61360000 0x1000>;
--
2.7.4
^ permalink raw reply related
* [PATCH v5 6/7] net: ethernet: bgmac: add NS2 support
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-1-git-send-email-jon.mason@broadcom.com>
Add support for the variant of amac hardware present in the Broadcom
Northstar2 based SoCs. Northstar2 requires an additional register to be
configured with the port speed/duplexity (NICPM). This can be added to
the link callback to hide it from the instances that do not use this.
Also, clearing of the pending interrupts on init is required due to
observed issues on some platforms.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +++++++++++++++++++++++++-
drivers/net/ethernet/broadcom/bgmac.c | 3 ++
drivers/net/ethernet/broadcom/bgmac.h | 1 +
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
index aed5dc5..fce63cf 100644
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -14,12 +14,21 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bcma/bcma.h>
+#include <linux/brcmphy.h>
#include <linux/etherdevice.h>
#include <linux/of_address.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include "bgmac.h"
+#define NICPM_IOMUX_CTRL 0x00000008
+
+#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000
+#define NICPM_IOMUX_CTRL_SPD_SHIFT 10
+#define NICPM_IOMUX_CTRL_SPD_10M 0
+#define NICPM_IOMUX_CTRL_SPD_100M 1
+#define NICPM_IOMUX_CTRL_SPD_1000M 2
+
static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset)
{
return readl(bgmac->plat.base + offset);
@@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
WARN_ON(1);
}
+static void bgmac_nicpm_speed_set(struct net_device *net_dev)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+ u32 val;
+
+ if (!bgmac->plat.nicpm_base)
+ return;
+
+ val = NICPM_IOMUX_CTRL_INIT_VAL;
+ switch (bgmac->net_dev->phydev->speed) {
+ default:
+ netdev_err(net_dev, "Unsupported speed. Defaulting to 1000Mb\n");
+ case SPEED_1000:
+ val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+ break;
+ case SPEED_100:
+ val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+ break;
+ case SPEED_10:
+ val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+ break;
+ }
+
+ writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL);
+
+ bgmac_adjust_link(bgmac->net_dev);
+}
+
static int platform_phy_connect(struct bgmac *bgmac)
{
struct phy_device *phy_dev;
- phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
- bgmac_adjust_link);
+ if (bgmac->plat.nicpm_base)
+ phy_dev = of_phy_get_and_connect(bgmac->net_dev,
+ bgmac->dev->of_node,
+ bgmac_nicpm_speed_set);
+ else
+ phy_dev = of_phy_get_and_connect(bgmac->net_dev,
+ bgmac->dev->of_node,
+ bgmac_adjust_link);
if (!phy_dev) {
dev_err(bgmac->dev, "Phy connect failed\n");
return -ENODEV;
@@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev)
if (IS_ERR(bgmac->plat.idm_base))
return PTR_ERR(bgmac->plat.idm_base);
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
+ if (regs) {
+ bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
+ regs);
+ if (IS_ERR(bgmac->plat.nicpm_base))
+ return PTR_ERR(bgmac->plat.nicpm_base);
+ }
+
bgmac->read = platform_bgmac_read;
bgmac->write = platform_bgmac_write;
bgmac->idm_read = platform_bgmac_idm_read;
@@ -213,6 +264,7 @@ static int bgmac_remove(struct platform_device *pdev)
static const struct of_device_id bgmac_of_enet_match[] = {
{.compatible = "brcm,amac",},
{.compatible = "brcm,nsp-amac",},
+ {.compatible = "brcm,ns2-amac",},
{},
};
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 4584958..a805cc8 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac)
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
static void bgmac_chip_init(struct bgmac *bgmac)
{
+ /* Clear any erroneously pending interrupts */
+ bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
+
/* 1 interrupt per received frame */
bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
index ea52ac3..b1820ea 100644
--- a/drivers/net/ethernet/broadcom/bgmac.h
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -463,6 +463,7 @@ struct bgmac {
struct {
void *base;
void *idm_base;
+ void *nicpm_base;
} plat;
struct {
struct bcma_device *core;
--
2.7.4
^ permalink raw reply related
* [PATCH v5 5/7] net: ethernet: bgmac: device tree phy enablement
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-1-git-send-email-jon.mason@broadcom.com>
Change the bgmac driver to allow for phy's defined by the device tree
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 ++++++++++++++++++++++++
drivers/net/ethernet/broadcom/bgmac-platform.c | 48 +++++++++++++++++++++++-
drivers/net/ethernet/broadcom/bgmac.c | 52 ++------------------------
drivers/net/ethernet/broadcom/bgmac.h | 7 ++++
4 files changed, 105 insertions(+), 50 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c
index c16ec3a..3e3efde 100644
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -80,6 +80,50 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask,
bcma_maskset32(bgmac->bcma.cmn, offset, mask, set);
}
+static int bcma_phy_connect(struct bgmac *bgmac)
+{
+ struct phy_device *phy_dev;
+ char bus_id[MII_BUS_ID_SIZE + 3];
+
+ /* Connect to the PHY */
+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
+ bgmac->phyaddr);
+ phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
+ PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(phy_dev)) {
+ dev_err(bgmac->dev, "PHY connecton failed\n");
+ return PTR_ERR(phy_dev);
+ }
+
+ return 0;
+}
+
+static int bcma_phy_direct_connect(struct bgmac *bgmac)
+{
+ struct fixed_phy_status fphy_status = {
+ .link = 1,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+ };
+ struct phy_device *phy_dev;
+ int err;
+
+ phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
+ if (!phy_dev || IS_ERR(phy_dev)) {
+ dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
+ return -ENODEV;
+ }
+
+ err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
+ PHY_INTERFACE_MODE_MII);
+ if (err) {
+ dev_err(bgmac->dev, "Connecting PHY failed\n");
+ return err;
+ }
+
+ return err;
+}
+
static const struct bcma_device_id bgmac_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT,
BCMA_ANY_REV, BCMA_ANY_CLASS),
@@ -275,6 +319,10 @@ static int bgmac_probe(struct bcma_device *core)
bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
+ if (bgmac->mii_bus)
+ bgmac->phy_connect = bcma_phy_connect;
+ else
+ bgmac->phy_connect = bcma_phy_direct_connect;
err = bgmac_enet_probe(bgmac);
if (err)
diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
index be52f27..aed5dc5 100644
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -16,6 +16,7 @@
#include <linux/bcma/bcma.h>
#include <linux/etherdevice.h>
#include <linux/of_address.h>
+#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include "bgmac.h"
@@ -86,6 +87,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
WARN_ON(1);
}
+static int platform_phy_connect(struct bgmac *bgmac)
+{
+ struct phy_device *phy_dev;
+
+ phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
+ bgmac_adjust_link);
+ if (!phy_dev) {
+ dev_err(bgmac->dev, "Phy connect failed\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int platform_phy_direct_connect(struct bgmac *bgmac)
+{
+ struct fixed_phy_status fphy_status = {
+ .link = 1,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+ };
+ struct phy_device *phy_dev;
+ int err;
+
+ phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
+ if (!phy_dev || IS_ERR(phy_dev)) {
+ dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
+ return -ENODEV;
+ }
+
+ err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
+ PHY_INTERFACE_MODE_MII);
+ if (err) {
+ dev_err(bgmac->dev, "Connecting PHY failed\n");
+ return err;
+ }
+
+ return err;
+}
+
static int bgmac_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -102,7 +143,6 @@ static int bgmac_probe(struct platform_device *pdev)
/* Set the features of the 4707 family */
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
- bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
@@ -151,6 +191,12 @@ static int bgmac_probe(struct platform_device *pdev)
bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
+ if (of_parse_phandle(np, "phy-handle", 0)) {
+ bgmac->phy_connect = platform_phy_connect;
+ } else {
+ bgmac->phy_connect = platform_phy_direct_connect;
+ bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
+ }
return bgmac_enet_probe(bgmac);
}
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 856379c..4584958 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1388,7 +1388,7 @@ static const struct ethtool_ops bgmac_ethtool_ops = {
* MII
**************************************************/
-static void bgmac_adjust_link(struct net_device *net_dev)
+void bgmac_adjust_link(struct net_device *net_dev)
{
struct bgmac *bgmac = netdev_priv(net_dev);
struct phy_device *phy_dev = net_dev->phydev;
@@ -1411,50 +1411,7 @@ static void bgmac_adjust_link(struct net_device *net_dev)
phy_print_status(phy_dev);
}
}
-
-static int bgmac_phy_connect_direct(struct bgmac *bgmac)
-{
- struct fixed_phy_status fphy_status = {
- .link = 1,
- .speed = SPEED_1000,
- .duplex = DUPLEX_FULL,
- };
- struct phy_device *phy_dev;
- int err;
-
- phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
- if (!phy_dev || IS_ERR(phy_dev)) {
- dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
- return -ENODEV;
- }
-
- err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
- PHY_INTERFACE_MODE_MII);
- if (err) {
- dev_err(bgmac->dev, "Connecting PHY failed\n");
- return err;
- }
-
- return err;
-}
-
-static int bgmac_phy_connect(struct bgmac *bgmac)
-{
- struct phy_device *phy_dev;
- char bus_id[MII_BUS_ID_SIZE + 3];
-
- /* Connect to the PHY */
- snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
- bgmac->phyaddr);
- phy_dev = phy_connect(bgmac->net_dev, bus_id, &bgmac_adjust_link,
- PHY_INTERFACE_MODE_MII);
- if (IS_ERR(phy_dev)) {
- dev_err(bgmac->dev, "PHY connecton failed\n");
- return PTR_ERR(phy_dev);
- }
-
- return 0;
-}
+EXPORT_SYMBOL_GPL(bgmac_adjust_link);
int bgmac_enet_probe(struct bgmac *info)
{
@@ -1507,10 +1464,7 @@ int bgmac_enet_probe(struct bgmac *info)
netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
- if (!bgmac->mii_bus)
- err = bgmac_phy_connect_direct(bgmac);
- else
- err = bgmac_phy_connect(bgmac);
+ err = bgmac_phy_connect(bgmac);
if (err) {
dev_err(bgmac->dev, "Cannot connect to phy\n");
goto err_dma_free;
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
index 80836b4..ea52ac3 100644
--- a/drivers/net/ethernet/broadcom/bgmac.h
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -513,10 +513,12 @@ struct bgmac {
u32 (*get_bus_clock)(struct bgmac *bgmac);
void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
u32 set);
+ int (*phy_connect)(struct bgmac *bgmac);
};
int bgmac_enet_probe(struct bgmac *info);
void bgmac_enet_remove(struct bgmac *bgmac);
+void bgmac_adjust_link(struct net_device *net_dev);
struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr);
void bcma_mdio_mii_unregister(struct mii_bus *mii_bus);
@@ -583,4 +585,9 @@ static inline void bgmac_set(struct bgmac *bgmac, u16 offset, u32 set)
{
bgmac_maskset(bgmac, offset, ~0, set);
}
+
+static inline int bgmac_phy_connect(struct bgmac *bgmac)
+{
+ return bgmac->phy_connect(bgmac);
+}
#endif /* _BGMAC_H */
--
2.7.4
^ permalink raw reply related
* [PATCH v5 4/7] Documentation: devicetree: net: add NS2 bindings to amac
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-1-git-send-email-jon.mason@broadcom.com>
Clean-up the documentation to the bgmac-amac driver, per suggestion by
Rob Herring, and add details for NS2 support.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt
index ba5ecc1..2fefa1a 100644
--- a/Documentation/devicetree/bindings/net/brcm,amac.txt
+++ b/Documentation/devicetree/bindings/net/brcm,amac.txt
@@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings
-------------------------------------------------------------
Required properties:
- - compatible: "brcm,amac" or "brcm,nsp-amac"
- - reg: Address and length of the GMAC registers,
- Address and length of the GMAC IDM registers
- - reg-names: Names of the registers. Must have both "amac_base" and
- "idm_base"
+ - compatible: "brcm,amac"
+ "brcm,nsp-amac"
+ "brcm,ns2-amac"
+ - reg: Address and length of the register set for the device. It
+ contains the information of registers in the same order as
+ described by reg-names
+ - reg-names: Names of the registers.
+ "amac_base": Address and length of the GMAC registers
+ "idm_base": Address and length of the GMAC IDM registers
+ "nicpm_base": Address and length of the NIC Port Manager
+ registers (required for Northstar2)
- interrupts: Interrupt number
Optional properties:
--
2.7.4
^ permalink raw reply related
* [PATCH v5 3/7] net: phy: broadcom: Add BCM54810 PHY entry
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-1-git-send-email-jon.mason@broadcom.com>
The BCM54810 PHY requires some semi-unique configuration, which results
in some additional configuration in addition to the standard config.
Also, some users of the BCM54810 require the PHY lanes to be swapped.
Since there is no way to detect this, add a device tree query to see if
it is applicable.
Inspired-by: Vikas Soni <vsoni@broadcom.com>
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
drivers/net/phy/Kconfig | 2 +-
drivers/net/phy/broadcom.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
include/linux/brcmphy.h | 9 +++++++
3 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 45f68ea..31967ca 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -217,7 +217,7 @@ config BROADCOM_PHY
select BCM_NET_PHYLIB
---help---
Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
- BCM5481 and BCM5482 PHYs.
+ BCM5481, BCM54810 and BCM5482 PHYs.
config CICADA_PHY
tristate "Cicada PHYs"
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 3a64b3d..b1e32e9 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -18,7 +18,7 @@
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/brcmphy.h>
-
+#include <linux/of.h>
#define BRCM_PHY_MODEL(phydev) \
((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
@@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
}
+static int bcm54810_config(struct phy_device *phydev)
+{
+ int rc, val;
+
+ val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
+ val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
+ rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
+ val);
+ if (rc < 0)
+ return rc;
+
+ val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
+ val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
+ val |= MII_BCM54XX_AUXCTL_MISC_WREN;
+ rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
+ val);
+ if (rc < 0)
+ return rc;
+
+ val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
+ val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
+ rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
/* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
static int bcm50610_a0_workaround(struct phy_device *phydev)
{
@@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev)
(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
bcm54xx_adjust_rxrefclk(phydev);
+ if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
+ err = bcm54810_config(phydev);
+ if (err)
+ return err;
+ }
+
bcm54xx_phydsp_config(phydev);
return 0;
@@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev)
static int bcm5481_config_aneg(struct phy_device *phydev)
{
+ struct device_node *np = phydev->mdio.dev.of_node;
int ret;
/* Aneg firsly. */
@@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
phy_write(phydev, 0x18, reg);
}
+ if (of_property_read_bool(np, "enet-phy-lane-swap")) {
+ /* Lane Swap - Undocumented register...magic! */
+ ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
+ 0x11B);
+ if (ret < 0)
+ return ret;
+ }
+
return ret;
}
@@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = {
.ack_interrupt = bcm_phy_ack_intr,
.config_intr = bcm_phy_config_intr,
}, {
+ .phy_id = PHY_ID_BCM54810,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Broadcom BCM54810",
+ .features = PHY_GBIT_FEATURES |
+ SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+ .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+ .config_init = bcm54xx_config_init,
+ .config_aneg = bcm5481_config_aneg,
+ .read_status = genphy_read_status,
+ .ack_interrupt = bcm_phy_ack_intr,
+ .config_intr = bcm_phy_config_intr,
+}, {
.phy_id = PHY_ID_BCM5482,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5482",
@@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
{ PHY_ID_BCM54616S, 0xfffffff0 },
{ PHY_ID_BCM5464, 0xfffffff0 },
{ PHY_ID_BCM5481, 0xfffffff0 },
+ { PHY_ID_BCM54810, 0xfffffff0 },
{ PHY_ID_BCM5482, 0xfffffff0 },
{ PHY_ID_BCM50610, 0xfffffff0 },
{ PHY_ID_BCM50610M, 0xfffffff0 },
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 0ed6691..848dc50 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -13,6 +13,7 @@
#define PHY_ID_BCM5241 0x0143bc30
#define PHY_ID_BCMAC131 0x0143bc70
#define PHY_ID_BCM5481 0x0143bca0
+#define PHY_ID_BCM54810 0x03625d00
#define PHY_ID_BCM5482 0x0143bcb0
#define PHY_ID_BCM5411 0x00206070
#define PHY_ID_BCM5421 0x002060e0
@@ -56,6 +57,7 @@
#define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00002000
#define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000
#define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000
+
/* Broadcom BCM7xxx specific workarounds */
#define PHY_BRCM_7XXX_REV(x) (((x) >> 8) & 0xff)
#define PHY_BRCM_7XXX_PATCH(x) ((x) & 0xff)
@@ -111,6 +113,7 @@
#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007
#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
+#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN (1 << 8)
#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007
@@ -192,6 +195,12 @@
#define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
#define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
+/* BCM54810 Registers */
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL (MII_BCM54XX_EXP_SEL_ER + 0x90)
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN (1 << 0)
+#define BCM54810_SHD_CLK_CTL 0x3
+#define BCM54810_SHD_CLK_CTL_GTXCLK_EN (1 << 9)
+
/*****************************************************************************/
/* Fast Ethernet Transceiver definitions. */
--
2.7.4
^ permalink raw reply related
* [PATCH v5 2/7] Documentation: devicetree: add PHY lane swap binding
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-1-git-send-email-jon.mason@broadcom.com>
Add the documentation for PHY lane swapping. This is a boolean entry to
notify the phy device drivers that the TX/RX lanes need to be swapped.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
Documentation/devicetree/bindings/net/phy.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
index bc1c3c8..4627da3 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -35,6 +35,10 @@ Optional Properties:
- broken-turn-around: If set, indicates the PHY device does not correctly
release the turn around line low at the end of a MDIO transaction.
+- enet-phy-lane-swap: If set, indicates the PHY will swap the TX/RX lanes to
+ compensate for the board being designed with the lanes swapped.
+
+
Example:
ethernet-phy at 0 {
--
2.7.4
^ permalink raw reply related
* [PATCH v5 1/7] net: phy: broadcom: add bcm54xx_auxctl_read
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478106488-11779-1-git-send-email-jon.mason@broadcom.com>
Add a helper function to read the AUXCTL register for the BCM54xx. This
mirrors the bcm54xx_auxctl_write function already present in the code.
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
drivers/net/phy/broadcom.c | 10 ++++++++++
include/linux/brcmphy.h | 1 +
2 files changed, 11 insertions(+)
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 583ef8a..3a64b3d 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver");
MODULE_AUTHOR("Maciej W. Rozycki");
MODULE_LICENSE("GPL");
+static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
+{
+ /* The register must be written to both the Shadow Register Select and
+ * the Shadow Read Register Selector
+ */
+ phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum |
+ regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
+ return phy_read(phydev, MII_BCM54XX_AUX_CTL);
+}
+
static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
{
return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 60def78..0ed6691 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -110,6 +110,7 @@
#define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX 0x0200
#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007
+#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007
--
2.7.4
^ permalink raw reply related
* [PATCH v5 0/7] add NS2 support to bgmac
From: Jon Mason @ 2016-11-02 17:08 UTC (permalink / raw)
To: linux-arm-kernel
Changes in v5:
* Change a pr_err to netdev_err (per Scott Branden)
* Reword the lane swap binding documentation (per Andrew Lunn)
Changes in v4:
* Actually send out the lane swap binding doc patch (Per Scott Branden)
* Remove unused #define (Per Andrew Lunn)
Changes in v3:
* Clean-up the bgmac DT binding doc (per Rob Herring)
* Document the lane swap binding and make it generic (Per Andrew Lunn)
Changes in v2:
* Remove the PHY power-on (per Andrew Lunn)
* Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn)
This results on none of the original PHY code from Vikas being
present. So, I'm removing him as an author and giving him
"Inspired-by" credit.
* Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian
Fainelli)
* Remove bgmac sleep (per Florian Fainelli)
* Re-add bgmac chip reset (per Florian Fainelli and Ray Jui)
* Rebased on latest net-next
* Added patch for bcm54xx_auxctl_read, which is used in the BCM54810
Add support for the amac found in the Broadcom Northstar2 SoC to the
bgmac driver. This necessitates adding support to connect to an
externally defined phy (as described in the device tree) in the driver.
These phy changes are in addition to the changes necessary to get NS2
working.
Jon Mason (7):
net: phy: broadcom: add bcm54xx_auxctl_read
Documentation: devicetree: add PHY lane swap binding
net: phy: broadcom: Add BCM54810 PHY entry
Documentation: devicetree: net: add NS2 bindings to amac
net: ethernet: bgmac: device tree phy enablement
net: ethernet: bgmac: add NS2 support
arm64: dts: NS2: add AMAC ethernet support
.../devicetree/bindings/net/brcm,amac.txt | 16 ++--
Documentation/devicetree/bindings/net/phy.txt | 4 +
arch/arm64/boot/dts/broadcom/ns2-svk.dts | 5 ++
arch/arm64/boot/dts/broadcom/ns2.dtsi | 12 +++
drivers/net/ethernet/broadcom/bgmac-bcma.c | 48 ++++++++++
drivers/net/ethernet/broadcom/bgmac-platform.c | 100 ++++++++++++++++++++-
drivers/net/ethernet/broadcom/bgmac.c | 55 ++----------
drivers/net/ethernet/broadcom/bgmac.h | 8 ++
drivers/net/phy/Kconfig | 2 +-
drivers/net/phy/broadcom.c | 68 +++++++++++++-
include/linux/brcmphy.h | 10 +++
11 files changed, 271 insertions(+), 57 deletions(-)
--
2.7.4
^ permalink raw reply
* [RFC PATCH v2 1/1] PCI/ACPI: xgene: Add ECAM quirk for X-Gene PCIe controller
From: Bjorn Helgaas @ 2016-11-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ff2976e86b4990fba80544e9916a85361afcc237.1477443743.git.dhdang@apm.com>
Hi Duc,
On Tue, Oct 25, 2016 at 06:24:32PM -0700, Duc Dang wrote:
> PCIe controllers in X-Gene SoCs is not ECAM compliant: software
> needs to configure additional controller's register to address
> device at bus:dev:function.
>
> This patch depends on "ECAM quirks handling for ARM64 platforms"
> series (http://www.spinics.net/lists/arm-kernel/msg530692.html,
> the series was also modified by Bjorn) to address the limitation
> above for X-Gene PCIe controller.
>
> The quirk will only be applied for X-Gene PCIe MCFG table with
> OEM revison 1, 2, 3 or 4 (PCIe controller v1 and v2 on X-Gene SoCs).
The quirks here contain some hard-coded address space consumed by
ECAM. The ECAM quirk itself is not a generic description of that
address space in the sense of a PCI BAR or an ACPI _CRS method, i.e.,
the quirk description is not enough to keep other parts of the kernel
from treating the address space as "available".
Can you add a note here in the changelog about how you are describing
this space generically? The standard solution is a PNP0C02 device
with _CRS that describes it.
It would be ideal if you could open a bugzilla at bugzilla.kernel.org
and attach there a dmesg log, /proc/iomem contents, and DSDT. This
would show both the generic PNP0C02 piece and the ECAM quirk piece.
BTW, I did refresh and re-push the pci/ecam-v6 branch where I'm
collecting this stuff, so if you want to rebase your patch on top of
that and test it, that would be great.
> Signed-off-by: Duc Dang <dhdang@apm.com>
> ---
> v2 changes:
> 1. Get rid of pci-xgene-ecam.c file and fold quirk code into pci-xgene.c
> 2. Redefine fixup array for X-Gene
> 3. Use devm_ioremap_resource to map csr_base
>
> drivers/acpi/pci_mcfg.c | 30 ++++++++
> drivers/pci/host/pci-xgene.c | 165 ++++++++++++++++++++++++++++++++++++++++++-
> include/linux/pci-ecam.h | 5 ++
> 3 files changed, 197 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
> index bb2c508..9dfc937 100644
> --- a/drivers/acpi/pci_mcfg.c
> +++ b/drivers/acpi/pci_mcfg.c
> @@ -96,6 +96,36 @@ struct mcfg_fixup {
> THUNDER_ECAM_MCFG(2, 12),
> THUNDER_ECAM_MCFG(2, 13),
> #endif
> +#ifdef CONFIG_PCI_XGENE
> +#define XGENE_V1_ECAM_MCFG(rev, seg) \
> + {"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
> + &xgene_v1_pcie_ecam_ops }
> +#define XGENE_V2_1_ECAM_MCFG(rev, seg) \
> + {"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
> + &xgene_v2_1_pcie_ecam_ops }
> +#define XGENE_V2_2_ECAM_MCFG(rev, seg) \
> + {"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
> + &xgene_v2_2_pcie_ecam_ops }
> +
> + /* X-Gene SoC with v1 PCIe controller */
> + XGENE_V1_ECAM_MCFG(1, 0),
> + XGENE_V1_ECAM_MCFG(1, 1),
> + XGENE_V1_ECAM_MCFG(1, 2),
> + XGENE_V1_ECAM_MCFG(1, 3),
> + XGENE_V1_ECAM_MCFG(1, 4),
> + XGENE_V1_ECAM_MCFG(2, 0),
> + XGENE_V1_ECAM_MCFG(2, 1),
> + XGENE_V1_ECAM_MCFG(2, 2),
> + XGENE_V1_ECAM_MCFG(2, 3),
> + XGENE_V1_ECAM_MCFG(2, 4),
> + /* X-Gene SoC with v2.1 PCIe controller */
> + XGENE_V2_1_ECAM_MCFG(3, 0),
> + XGENE_V2_1_ECAM_MCFG(3, 1),
> + /* X-Gene SoC with v2.2 PCIe controller */
> + XGENE_V2_2_ECAM_MCFG(4, 0),
> + XGENE_V2_2_ECAM_MCFG(4, 1),
> + XGENE_V2_2_ECAM_MCFG(4, 2),
> +#endif
> };
>
> static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
> diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
> index 1de23d7..d6aa642 100644
> --- a/drivers/pci/host/pci-xgene.c
> +++ b/drivers/pci/host/pci-xgene.c
> @@ -27,6 +27,8 @@
> #include <linux/of_irq.h>
> #include <linux/of_pci.h>
> #include <linux/pci.h>
> +#include <linux/pci-acpi.h>
> +#include <linux/pci-ecam.h>
> #include <linux/platform_device.h>
> #include <linux/slab.h>
>
> @@ -64,6 +66,7 @@
> /* PCIe IP version */
> #define XGENE_PCIE_IP_VER_UNKN 0
> #define XGENE_PCIE_IP_VER_1 1
> +#define XGENE_PCIE_IP_VER_2 2
>
> struct xgene_pcie_port {
> struct device_node *node;
> @@ -97,7 +100,15 @@ static inline u32 pcie_bar_low_val(u32 addr, u32 flags)
> */
> static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus)
> {
> - struct xgene_pcie_port *port = bus->sysdata;
> + struct pci_config_window *cfg;
> + struct xgene_pcie_port *port;
> +
> + if (acpi_disabled)
> + port = bus->sysdata;
> + else {
> + cfg = bus->sysdata;
> + port = cfg->priv;
> + }
>
> if (bus->number >= (bus->primary + 1))
> return port->cfg_base + AXI_EP_CFG_ACCESS;
> @@ -111,10 +122,18 @@ static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus)
> */
> static void xgene_pcie_set_rtdid_reg(struct pci_bus *bus, uint devfn)
> {
> - struct xgene_pcie_port *port = bus->sysdata;
> + struct pci_config_window *cfg;
> + struct xgene_pcie_port *port;
> unsigned int b, d, f;
> u32 rtdid_val = 0;
>
> + if (acpi_disabled)
> + port = bus->sysdata;
> + else {
> + cfg = bus->sysdata;
> + port = cfg->priv;
> + }
> +
> b = bus->number;
> d = PCI_SLOT(devfn);
> f = PCI_FUNC(devfn);
> @@ -158,7 +177,15 @@ static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
> static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
> int where, int size, u32 *val)
> {
> - struct xgene_pcie_port *port = bus->sysdata;
> + struct pci_config_window *cfg;
> + struct xgene_pcie_port *port;
> +
> + if (acpi_disabled)
> + port = bus->sysdata;
> + else {
> + cfg = bus->sysdata;
> + port = cfg->priv;
> + }
>
> if (pci_generic_config_read32(bus, devfn, where & ~0x3, 4, val) !=
> PCIBIOS_SUCCESSFUL)
> @@ -189,6 +216,138 @@ static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
> .write = pci_generic_config_write32,
> };
>
> +#ifdef CONFIG_ACPI
> +static struct resource xgene_v1_csr_res[] = {
> + [0] = DEFINE_RES_MEM(0x1f2b0000UL, SZ_64K),
> + [1] = DEFINE_RES_MEM(0x1f2c0000UL, SZ_64K),
> + [2] = DEFINE_RES_MEM(0x1f2d0000UL, SZ_64K),
> + [3] = DEFINE_RES_MEM(0x1f500000UL, SZ_64K),
> + [4] = DEFINE_RES_MEM(0x1f510000UL, SZ_64K),
> +};
> +
> +static int xgene_v1_pcie_ecam_init(struct pci_config_window *cfg)
> +{
> + struct acpi_device *adev = to_acpi_device(cfg->parent);
> + struct acpi_pci_root *root = acpi_driver_data(adev);
> + struct device *dev = cfg->parent;
> + struct xgene_pcie_port *port;
> + struct resource *csr;
> +
> + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> + if (!port)
> + return -ENOMEM;
> +
> + csr = &xgene_v1_csr_res[root->segment];
> + port->csr_base = devm_ioremap_resource(dev, csr);
> + if (IS_ERR(port->csr_base)) {
> + kfree(port);
> + return -ENOMEM;
> + }
> +
> + port->cfg_base = cfg->win;
> + port->version = XGENE_PCIE_IP_VER_1;
> +
> + cfg->priv = port;
> +
> + return 0;
> +}
> +
> +struct pci_ecam_ops xgene_v1_pcie_ecam_ops = {
> + .bus_shift = 16,
> + .init = xgene_v1_pcie_ecam_init,
> + .pci_ops = {
> + .map_bus = xgene_pcie_map_bus,
> + .read = xgene_pcie_config_read32,
> + .write = pci_generic_config_write,
> + }
> +};
> +
> +static struct resource xgene_v2_1_csr_res[] = {
> + [0] = DEFINE_RES_MEM(0x1f2b0000UL, SZ_64K),
> + [1] = DEFINE_RES_MEM(0x1f2c0000UL, SZ_64K),
> +};
> +
> +static int xgene_v2_1_pcie_ecam_init(struct pci_config_window *cfg)
> +{
> + struct acpi_device *adev = to_acpi_device(cfg->parent);
> + struct acpi_pci_root *root = acpi_driver_data(adev);
> + struct device *dev = cfg->parent;
> + struct xgene_pcie_port *port;
> + struct resource *csr;
> +
> + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> + if (!port)
> + return -ENOMEM;
> +
> + csr = &xgene_v2_1_csr_res[root->segment];
> + port->csr_base = devm_ioremap_resource(dev, csr);
> + if (IS_ERR(port->csr_base)) {
> + kfree(port);
> + return -ENOMEM;
> + }
> +
> + port->cfg_base = cfg->win;
> + port->version = XGENE_PCIE_IP_VER_2;
> +
> + cfg->priv = port;
> +
> + return 0;
> +}
> +
> +struct pci_ecam_ops xgene_v2_1_pcie_ecam_ops = {
> + .bus_shift = 16,
> + .init = xgene_v2_1_pcie_ecam_init,
> + .pci_ops = {
> + .map_bus = xgene_pcie_map_bus,
> + .read = xgene_pcie_config_read32,
> + .write = pci_generic_config_write,
> + }
> +};
> +
> +static struct resource xgene_v2_2_csr_res[] = {
> + [0] = DEFINE_RES_MEM(0x1f2b0000UL, SZ_64K),
> + [1] = DEFINE_RES_MEM(0x1f500000UL, SZ_64K),
> + [2] = DEFINE_RES_MEM(0x1f2d0000UL, SZ_64K),
> +};
> +
> +static int xgene_v2_2_pcie_ecam_init(struct pci_config_window *cfg)
> +{
> + struct acpi_device *adev = to_acpi_device(cfg->parent);
> + struct acpi_pci_root *root = acpi_driver_data(adev);
> + struct device *dev = cfg->parent;
> + struct xgene_pcie_port *port;
> + struct resource *csr;
> +
> + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> + if (!port)
> + return -ENOMEM;
> +
> + csr = &xgene_v2_2_csr_res[root->segment];
> + port->csr_base = devm_ioremap_resource(dev, csr);
> + if (IS_ERR(port->csr_base)) {
> + kfree(port);
> + return -ENOMEM;
> + }
> +
> + port->cfg_base = cfg->win;
> + port->version = XGENE_PCIE_IP_VER_2;
> +
> + cfg->priv = port;
> +
> + return 0;
> +}
> +
> +struct pci_ecam_ops xgene_v2_2_pcie_ecam_ops = {
> + .bus_shift = 16,
> + .init = xgene_v2_2_pcie_ecam_init,
> + .pci_ops = {
> + .map_bus = xgene_pcie_map_bus,
> + .read = xgene_pcie_config_read32,
> + .write = pci_generic_config_write,
> + }
> +};
> +#endif
> +
> static u64 xgene_pcie_set_ib_mask(struct xgene_pcie_port *port, u32 addr,
> u32 flags, u64 size)
> {
> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
> index 35f0e81..40da3e7 100644
> --- a/include/linux/pci-ecam.h
> +++ b/include/linux/pci-ecam.h
> @@ -65,6 +65,11 @@ void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn,
> #ifdef CONFIG_PCI_HOST_THUNDER_ECAM
> extern struct pci_ecam_ops pci_thunder_ecam_ops;
> #endif
> +#ifdef CONFIG_PCI_XGENE
> +extern struct pci_ecam_ops xgene_v1_pcie_ecam_ops;
> +extern struct pci_ecam_ops xgene_v2_1_pcie_ecam_ops;
> +extern struct pci_ecam_ops xgene_v2_2_pcie_ecam_ops;
> +#endif
>
> #ifdef CONFIG_PCI_HOST_GENERIC
> /* for DT-based PCI controllers that support ECAM */
> --
> 1.9.1
>
^ permalink raw reply
* [PATCH v4 6/7] net: ethernet: bgmac: add NS2 support
From: Jon Mason @ 2016-11-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161101210512.GB27191@broadcom.com>
On Tue, Nov 01, 2016 at 05:05:13PM -0400, Jon Mason wrote:
> On Tue, Nov 01, 2016 at 01:34:30PM -0700, Scott Branden wrote:
> > One change in this patch
> >
> > On 16-11-01 01:04 PM, Jon Mason wrote:
> > >Add support for the variant of amac hardware present in the Broadcom
> > >Northstar2 based SoCs. Northstar2 requires an additional register to be
> > >configured with the port speed/duplexity (NICPM). This can be added to
> > >the link callback to hide it from the instances that do not use this.
> > >Also, clearing of the pending interrupts on init is required due to
> > >observed issues on some platforms.
> > >
> > >Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> > >---
> > > drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +++++++++++++++++++++++++-
> > > drivers/net/ethernet/broadcom/bgmac.c | 3 ++
> > > drivers/net/ethernet/broadcom/bgmac.h | 1 +
> > > 3 files changed, 58 insertions(+), 2 deletions(-)
> > >
> > >diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
> > >index aed5dc5..f6d48c7 100644
> > >--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
> > >+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
> > >@@ -14,12 +14,21 @@
> > > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > >
> > > #include <linux/bcma/bcma.h>
> > >+#include <linux/brcmphy.h>
> > > #include <linux/etherdevice.h>
> > > #include <linux/of_address.h>
> > > #include <linux/of_mdio.h>
> > > #include <linux/of_net.h>
> > > #include "bgmac.h"
> > >
> > >+#define NICPM_IOMUX_CTRL 0x00000008
> > >+
> > >+#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000
> > >+#define NICPM_IOMUX_CTRL_SPD_SHIFT 10
> > >+#define NICPM_IOMUX_CTRL_SPD_10M 0
> > >+#define NICPM_IOMUX_CTRL_SPD_100M 1
> > >+#define NICPM_IOMUX_CTRL_SPD_1000M 2
> > >+
> > > static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset)
> > > {
> > > return readl(bgmac->plat.base + offset);
> > >@@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
> > > WARN_ON(1);
> > > }
> > >
> > >+static void bgmac_nicpm_speed_set(struct net_device *net_dev)
> > >+{
> > >+ struct bgmac *bgmac = netdev_priv(net_dev);
> > >+ u32 val;
> > >+
> > >+ if (!bgmac->plat.nicpm_base)
> > >+ return;
> > >+
> > >+ val = NICPM_IOMUX_CTRL_INIT_VAL;
> > >+ switch (bgmac->net_dev->phydev->speed) {
> > >+ default:
> > >+ pr_err("Unsupported speed. Defaulting to 1000Mb\n");
> > This should be dev_err
>
> It should probably be netdev_err (and there are a few instances below
> that should probably be changed to netdev_err as well).
Actually, the other instances I referenced above should not be
netdev_err, as they are enountered before the netdev is created. So,
dev_err is correct for them.
That being said, the original pr_err that Scott referenced should be
netdev_err (as it is encountered after the netdev is created). v5 will
make that change.
Thanks,
Jon
>
> Thanks,
> Jon
>
> > >+ case SPEED_1000:
> > >+ val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT;
> > >+ break;
> > >+ case SPEED_100:
> > >+ val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT;
> > >+ break;
> > >+ case SPEED_10:
> > >+ val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT;
> > >+ break;
> > >+ }
> > >+
> > >+ writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL);
> > >+
> > >+ bgmac_adjust_link(bgmac->net_dev);
> > >+}
> > >+
> > > static int platform_phy_connect(struct bgmac *bgmac)
> > > {
> > > struct phy_device *phy_dev;
> > >
> > >- phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
> > >- bgmac_adjust_link);
> > >+ if (bgmac->plat.nicpm_base)
> > >+ phy_dev = of_phy_get_and_connect(bgmac->net_dev,
> > >+ bgmac->dev->of_node,
> > >+ bgmac_nicpm_speed_set);
> > >+ else
> > >+ phy_dev = of_phy_get_and_connect(bgmac->net_dev,
> > >+ bgmac->dev->of_node,
> > >+ bgmac_adjust_link);
> > > if (!phy_dev) {
> > > dev_err(bgmac->dev, "Phy connect failed\n");
> > > return -ENODEV;
> > >@@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev)
> > > if (IS_ERR(bgmac->plat.idm_base))
> > > return PTR_ERR(bgmac->plat.idm_base);
> > >
> > >+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
> > >+ if (regs) {
> > >+ bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
> > >+ regs);
> > >+ if (IS_ERR(bgmac->plat.nicpm_base))
> > >+ return PTR_ERR(bgmac->plat.nicpm_base);
> > >+ }
> > >+
> > > bgmac->read = platform_bgmac_read;
> > > bgmac->write = platform_bgmac_write;
> > > bgmac->idm_read = platform_bgmac_idm_read;
> > >@@ -213,6 +264,7 @@ static int bgmac_remove(struct platform_device *pdev)
> > > static const struct of_device_id bgmac_of_enet_match[] = {
> > > {.compatible = "brcm,amac",},
> > > {.compatible = "brcm,nsp-amac",},
> > >+ {.compatible = "brcm,ns2-amac",},
> > > {},
> > > };
> > >
> > >diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
> > >index 4584958..a805cc8 100644
> > >--- a/drivers/net/ethernet/broadcom/bgmac.c
> > >+++ b/drivers/net/ethernet/broadcom/bgmac.c
> > >@@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac)
> > > /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
> > > static void bgmac_chip_init(struct bgmac *bgmac)
> > > {
> > >+ /* Clear any erroneously pending interrupts */
> > >+ bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
> > >+
> > > /* 1 interrupt per received frame */
> > > bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
> > >
> > >diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
> > >index ea52ac3..b1820ea 100644
> > >--- a/drivers/net/ethernet/broadcom/bgmac.h
> > >+++ b/drivers/net/ethernet/broadcom/bgmac.h
> > >@@ -463,6 +463,7 @@ struct bgmac {
> > > struct {
> > > void *base;
> > > void *idm_base;
> > >+ void *nicpm_base;
> > > } plat;
> > > struct {
> > > struct bcma_device *core;
> > >
^ permalink raw reply
* Applied "ASoC: sun4i-codec: Enable bus clock after getting GPIO" to the asoc tree
From: Mark Brown @ 2016-11-02 16:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161101063155.15826-1-wens@csie.org>
The patch
ASoC: sun4i-codec: Enable bus clock after getting GPIO
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 3716a891d65cc04217da1af5f2bccb7eaf6092c2 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Tue, 1 Nov 2016 14:31:55 +0800
Subject: [PATCH] ASoC: sun4i-codec: Enable bus clock after getting GPIO
In the current probe function the GPIO is acquired after the codec's
bus clock is enabled. However if it fails to acquire the GPIO due to
a deferred probe, it does not disable the bus clock before bailing out.
This would result in the clock being enabled multiple times.
Move the code that enables the bus clock after the part that gets the
GPIO, maintaining a separation between resource acquisition and device
enablement in the probe function.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/sunxi/sun4i-codec.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index a60707761abf..56ed9472e89f 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -829,12 +829,6 @@ static int sun4i_codec_probe(struct platform_device *pdev)
return PTR_ERR(scodec->clk_module);
}
- /* Enable the bus clock */
- if (clk_prepare_enable(scodec->clk_apb)) {
- dev_err(&pdev->dev, "Failed to enable the APB clock\n");
- return -EINVAL;
- }
-
scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
GPIOD_OUT_LOW);
if (IS_ERR(scodec->gpio_pa)) {
@@ -844,6 +838,12 @@ static int sun4i_codec_probe(struct platform_device *pdev)
return ret;
}
+ /* Enable the bus clock */
+ if (clk_prepare_enable(scodec->clk_apb)) {
+ dev_err(&pdev->dev, "Failed to enable the APB clock\n");
+ return -EINVAL;
+ }
+
/* DMA configuration for TX FIFO */
scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
scodec->playback_dma_data.maxburst = 4;
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: dapm: Support second register for DAPM control updates" to the asoc tree
From: Mark Brown @ 2016-11-02 16:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161102073601.8659-2-wens@csie.org>
The patch
ASoC: dapm: Support second register for DAPM control updates
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From e411b0b5eb9b65257a050eac333d181d6e00e2c6 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Wed, 2 Nov 2016 15:35:58 +0800
Subject: [PATCH] ASoC: dapm: Support second register for DAPM control updates
To support double channel shared controls split across 2 registers, one
for each channel, we must be able to update both registers together.
Add a second set of register fields to struct snd_soc_dapm_update, and
update the DAPM control writeback (put) callbacks to support this.
For codecs that use custom events which call into DAPM to do updates,
also clear struct snd_soc_dapm_update before using it, so the second
set of fields remains clean.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
include/sound/soc-dapm.h | 4 ++++
sound/soc/codecs/adau17x1.c | 2 +-
sound/soc/codecs/tlv320aic3x.c | 2 +-
sound/soc/codecs/wm9712.c | 2 +-
sound/soc/codecs/wm9713.c | 2 +-
sound/soc/soc-dapm.c | 13 +++++++++++--
6 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index f60d755f7ac6..d5f4677776ce 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -615,6 +615,10 @@ struct snd_soc_dapm_update {
int reg;
int mask;
int val;
+ int reg2;
+ int mask2;
+ int val2;
+ bool has_second_set;
};
struct snd_soc_dapm_wcache {
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index 439aa3ff1f99..b36511d965c8 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -160,7 +160,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau *adau = snd_soc_codec_get_drvdata(codec);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- struct snd_soc_dapm_update update;
+ struct snd_soc_dapm_update update = { 0 };
unsigned int stream = e->shift_l;
unsigned int val, change;
int reg;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5a8d96ec058c..8877b74b0510 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -157,7 +157,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
unsigned short val;
- struct snd_soc_dapm_update update;
+ struct snd_soc_dapm_update update = { 0 };
int connect, change;
val = (ucontrol->value.integer.value[0] & mask);
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 557709eac698..85f7c5bb8b82 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -187,7 +187,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
unsigned int mixer, mask, shift, old;
- struct snd_soc_dapm_update update;
+ struct snd_soc_dapm_update update = { 0 };
bool change;
mixer = mc->shift >> 8;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index e4301ddb1b84..7e4822185feb 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -231,7 +231,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
unsigned int mixer, mask, shift, old;
- struct snd_soc_dapm_update update;
+ struct snd_soc_dapm_update update = { 0 };
bool change;
mixer = mc->shift >> 8;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 3bbe32ee4630..32e7af9b93d5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1626,6 +1626,15 @@ static void dapm_widget_update(struct snd_soc_card *card)
dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n",
w->name, ret);
+ if (update->has_second_set) {
+ ret = soc_dapm_update_bits(w->dapm, update->reg2,
+ update->mask2, update->val2);
+ if (ret < 0)
+ dev_err(w->dapm->dev,
+ "ASoC: %s DAPM update failed: %d\n",
+ w->name, ret);
+ }
+
for (wi = 0; wi < wlist->num_widgets; wi++) {
w = wlist->widgets[wi];
@@ -3084,7 +3093,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
unsigned int invert = mc->invert;
unsigned int val;
int connect, change, reg_change = 0;
- struct snd_soc_dapm_update update;
+ struct snd_soc_dapm_update update = { NULL };
int ret = 0;
if (snd_soc_volsw_is_stereo(mc))
@@ -3192,7 +3201,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
unsigned int *item = ucontrol->value.enumerated.item;
unsigned int val, change, reg_change = 0;
unsigned int mask;
- struct snd_soc_dapm_update update;
+ struct snd_soc_dapm_update update = { NULL };
int ret = 0;
if (item[0] >= e->items)
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: dapm: Implement stereo mixer control support" to the asoc tree
From: Mark Brown @ 2016-11-02 16:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161102073601.8659-3-wens@csie.org>
The patch
ASoC: dapm: Implement stereo mixer control support
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From e7aa450fe17890e59db7d3c2d8eff5b6b41fc531 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Wed, 2 Nov 2016 15:35:59 +0800
Subject: [PATCH] ASoC: dapm: Implement stereo mixer control support
While DAPM is mono or single channel, its controls can be shared between
widgets, such as sharing one stereo mixer control between the left and
right channel widgets. An example such as the following routes
[Line In Left]----------<Line In Playback Switch>-------[Left Mixer]
^
^ ^ | ^
(inputs) (paths) <shared stereo mixer control> (outputs)
v v | v
v
[Line In Right]---------<Line In Playback Switch>-------[Right Mixer]
where we have separate widgets and paths for the left and right channels
from "Line In" to "Mixer", but a shared stereo mixer control for the
2 paths.
This patch introduces support for such shared mixer controls, allowing
more than 1 path to be attached to a single stereo control, and being
able to control left/right channels independently.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/soc-dapm.c | 141 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 112 insertions(+), 29 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 32e7af9b93d5..27dd02e57b31 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -330,6 +330,11 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
case snd_soc_dapm_mixer_named_ctl:
mc = (struct soc_mixer_control *)kcontrol->private_value;
+ if (mc->autodisable && snd_soc_volsw_is_stereo(mc))
+ dev_warn(widget->dapm->dev,
+ "ASoC: Unsupported stereo autodisable control '%s'\n",
+ ctrl_name);
+
if (mc->autodisable) {
struct snd_soc_dapm_widget template;
@@ -723,7 +728,8 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
}
/* set up initial codec paths */
-static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
+static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i,
+ int nth_path)
{
struct soc_mixer_control *mc = (struct soc_mixer_control *)
p->sink->kcontrol_news[i].private_value;
@@ -736,7 +742,25 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
if (reg != SND_SOC_NOPM) {
soc_dapm_read(p->sink->dapm, reg, &val);
- val = (val >> shift) & mask;
+ /*
+ * The nth_path argument allows this function to know
+ * which path of a kcontrol it is setting the initial
+ * status for. Ideally this would support any number
+ * of paths and channels. But since kcontrols only come
+ * in mono and stereo variants, we are limited to 2
+ * channels.
+ *
+ * The following code assumes for stereo controls the
+ * first path is the left channel, and all remaining
+ * paths are the right channel.
+ */
+ if (snd_soc_volsw_is_stereo(mc) && nth_path > 0) {
+ if (reg != mc->rreg)
+ soc_dapm_read(p->sink->dapm, mc->rreg, &val);
+ val = (val >> mc->rshift) & mask;
+ } else {
+ val = (val >> shift) & mask;
+ }
if (invert)
val = max - val;
p->connect = !!val;
@@ -749,13 +773,13 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_path *path, const char *control_name)
{
- int i;
+ int i, nth_path = 0;
/* search for mixer kcontrol */
for (i = 0; i < path->sink->num_kcontrols; i++) {
if (!strcmp(control_name, path->sink->kcontrol_news[i].name)) {
path->name = path->sink->kcontrol_news[i].name;
- dapm_set_mixer_path_status(path, i);
+ dapm_set_mixer_path_status(path, i, nth_path++);
return 0;
}
}
@@ -2186,7 +2210,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
/* test and update the power status of a mixer or switch widget */
static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
- struct snd_kcontrol *kcontrol, int connect)
+ struct snd_kcontrol *kcontrol,
+ int connect, int rconnect)
{
struct snd_soc_dapm_path *path;
int found = 0;
@@ -2195,8 +2220,33 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
/* find dapm widget path assoc with kcontrol */
dapm_kcontrol_for_each_path(path, kcontrol) {
+ /*
+ * Ideally this function should support any number of
+ * paths and channels. But since kcontrols only come
+ * in mono and stereo variants, we are limited to 2
+ * channels.
+ *
+ * The following code assumes for stereo controls the
+ * first path (when 'found == 0') is the left channel,
+ * and all remaining paths (when 'found == 1') are the
+ * right channel.
+ *
+ * A stereo control is signified by a valid 'rconnect'
+ * value, either 0 for unconnected, or >= 0 for connected.
+ * This is chosen instead of using snd_soc_volsw_is_stereo,
+ * so that the behavior of snd_soc_dapm_mixer_update_power
+ * doesn't change even when the kcontrol passed in is
+ * stereo.
+ *
+ * It passes 'connect' as the path connect status for
+ * the left channel, and 'rconnect' for the right
+ * channel.
+ */
+ if (found && rconnect >= 0)
+ soc_dapm_connect_path(path, rconnect, "mixer update");
+ else
+ soc_dapm_connect_path(path, connect, "mixer update");
found = 1;
- soc_dapm_connect_path(path, connect, "mixer update");
}
if (found)
@@ -2214,7 +2264,7 @@ int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
card->update = update;
- ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
+ ret = soc_dapm_mixer_update_power(card, kcontrol, connect, -1);
card->update = NULL;
mutex_unlock(&card->dapm_mutex);
if (ret > 0)
@@ -3039,22 +3089,28 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
int reg = mc->reg;
unsigned int shift = mc->shift;
int max = mc->max;
+ unsigned int width = fls(max);
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
- unsigned int val;
+ unsigned int reg_val, val, rval = 0;
int ret = 0;
- if (snd_soc_volsw_is_stereo(mc))
- dev_warn(dapm->dev,
- "ASoC: Control '%s' is stereo, which is not supported\n",
- kcontrol->id.name);
-
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM) {
- ret = soc_dapm_read(dapm, reg, &val);
- val = (val >> shift) & mask;
+ ret = soc_dapm_read(dapm, reg, ®_val);
+ val = (reg_val >> shift) & mask;
+
+ if (ret == 0 && reg != mc->rreg)
+ ret = soc_dapm_read(dapm, mc->rreg, ®_val);
+
+ if (snd_soc_volsw_is_stereo(mc))
+ rval = (reg_val >> mc->rshift) & mask;
} else {
- val = dapm_kcontrol_get_value(kcontrol);
+ reg_val = dapm_kcontrol_get_value(kcontrol);
+ val = reg_val & mask;
+
+ if (snd_soc_volsw_is_stereo(mc))
+ rval = (reg_val >> width) & mask;
}
mutex_unlock(&card->dapm_mutex);
@@ -3066,6 +3122,13 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
else
ucontrol->value.integer.value[0] = val;
+ if (snd_soc_volsw_is_stereo(mc)) {
+ if (invert)
+ ucontrol->value.integer.value[1] = max - rval;
+ else
+ ucontrol->value.integer.value[1] = rval;
+ }
+
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
@@ -3089,46 +3152,66 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
int reg = mc->reg;
unsigned int shift = mc->shift;
int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
+ unsigned int width = fls(max);
+ unsigned int mask = (1 << width) - 1;
unsigned int invert = mc->invert;
- unsigned int val;
- int connect, change, reg_change = 0;
+ unsigned int val, rval = 0;
+ int connect, rconnect = -1, change, reg_change = 0;
struct snd_soc_dapm_update update = { NULL };
int ret = 0;
- if (snd_soc_volsw_is_stereo(mc))
- dev_warn(dapm->dev,
- "ASoC: Control '%s' is stereo, which is not supported\n",
- kcontrol->id.name);
-
val = (ucontrol->value.integer.value[0] & mask);
connect = !!val;
if (invert)
val = max - val;
+ if (snd_soc_volsw_is_stereo(mc)) {
+ rval = (ucontrol->value.integer.value[1] & mask);
+ rconnect = !!rval;
+ if (invert)
+ rval = max - rval;
+ }
+
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
- change = dapm_kcontrol_set_value(kcontrol, val);
+ /* This assumes field width < (bits in unsigned int / 2) */
+ if (width > sizeof(unsigned int) * 8 / 2)
+ dev_warn(dapm->dev,
+ "ASoC: control %s field width limit exceeded\n",
+ kcontrol->id.name);
+ change = dapm_kcontrol_set_value(kcontrol, val | (rval << width));
if (reg != SND_SOC_NOPM) {
- mask = mask << shift;
val = val << shift;
+ rval = rval << mc->rshift;
+
+ reg_change = soc_dapm_test_bits(dapm, reg, mask << shift, val);
- reg_change = soc_dapm_test_bits(dapm, reg, mask, val);
+ if (snd_soc_volsw_is_stereo(mc))
+ reg_change |= soc_dapm_test_bits(dapm, mc->rreg,
+ mask << mc->rshift,
+ rval);
}
if (change || reg_change) {
if (reg_change) {
+ if (snd_soc_volsw_is_stereo(mc)) {
+ update.has_second_set = true;
+ update.reg2 = mc->rreg;
+ update.mask2 = mask << mc->rshift;
+ update.val2 = rval;
+ }
update.kcontrol = kcontrol;
update.reg = reg;
- update.mask = mask;
+ update.mask = mask << shift;
update.val = val;
card->update = &update;
}
change |= reg_change;
- ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
+ ret = soc_dapm_mixer_update_power(card, kcontrol, connect,
+ rconnect);
card->update = NULL;
}
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: dapm: Introduce DAPM_DOUBLE dual channel control type" to the asoc tree
From: Mark Brown @ 2016-11-02 16:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161003110804.28235-4-wens@csie.org>
The patch
ASoC: dapm: Introduce DAPM_DOUBLE dual channel control type
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 9ee7ef31b5a07cdca88cae023c613e045af935b9 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Wed, 2 Nov 2016 15:36:00 +0800
Subject: [PATCH] ASoC: dapm: Introduce DAPM_DOUBLE dual channel control type
A DAPM_DOUBLE control type can be used for dual channel mixer input
selectors / mute controls in one register, possibly toggling both
channels together.
The control is meant to be shared by 2 widgets, 1 for each channel,
such that the mixer control exposed to userspace remains a combined
stereo control.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
include/sound/soc-dapm.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index d5f4677776ce..f74ec19687f8 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -272,6 +272,11 @@ struct device;
/* dapm kcontrol types */
+#define SOC_DAPM_DOUBLE(xname, reg, lshift, rshift, max, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_soc_info_volsw, \
+ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
+ .private_value = SOC_DOUBLE_VALUE(reg, lshift, rshift, max, invert, 0) }
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
--
2.10.1
^ permalink raw reply related
* Applied "ASoC: dapm: Introduce DAPM_DOUBLE_R dual channel dual register control type" to the asoc tree
From: Mark Brown @ 2016-11-02 16:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161003110804.28235-5-wens@csie.org>
The patch
ASoC: dapm: Introduce DAPM_DOUBLE_R dual channel dual register control type
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 02866eab0f0d88c4b6a68de72022c2b26f0359b5 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens@csie.org>
Date: Wed, 2 Nov 2016 15:36:01 +0800
Subject: [PATCH] ASoC: dapm: Introduce DAPM_DOUBLE_R dual channel dual
register control type
A DAPM_DOUBLE_R control type can be used for dual channel mixer input
selectors / mute controls across 2 registers, possibly toggling both
channels together.
The control is meant to be shared by 2 widgets, 1 for each channel,
such that the mixer control exposed to userspace remains a combined
stereo control.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
include/sound/soc-dapm.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index f74ec19687f8..a466f4bdc835 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -277,6 +277,11 @@ struct device;
.info = snd_soc_info_volsw, \
.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
.private_value = SOC_DOUBLE_VALUE(reg, lshift, rshift, max, invert, 0) }
+#define SOC_DAPM_DOUBLE_R(xname, lreg, rreg, shift, max, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_soc_info_volsw, \
+ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
+ .private_value = SOC_DOUBLE_R_VALUE(lreg, rreg, shift, max, invert) }
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
--
2.10.1
^ permalink raw reply related
* arm64 build failure with CONFIG_ARM64_LSE_ATOMICS=y
From: Artem Savkov @ 2016-11-02 16:44 UTC (permalink / raw)
To: linux-arm-kernel
Hello Catalin,
Looks like your patch "efd9e03 arm64: Use static keys for CPU features"
breaks arm64 build with "CONFIG_ARM64_LSE_ATOMICS=y" because it creates a
circular dependency for asm/lse.h through jump_label.h:
CC arch/arm64/kernel/asm-offsets.s
In file included from ./arch/arm64/include/asm/atomic.h:34:0,
from ./include/linux/atomic.h:4,
from ./include/linux/jump_label.h:169,
from ./arch/arm64/include/asm/cpufeature.h:12,
from ./arch/arm64/include/asm/alternative.h:4,
from ./arch/arm64/include/asm/lse.h:7,
from ./arch/arm64/include/asm/spinlock.h:19,
from ./include/linux/spinlock.h:87,
from ./include/linux/seqlock.h:35,
from ./include/linux/time.h:5,
from ./include/uapi/linux/timex.h:56,
from ./include/linux/timex.h:56,
from ./include/linux/sched.h:19,
from arch/arm64/kernel/asm-offsets.c:21:
./arch/arm64/include/asm/atomic_lse.h: In function ?atomic_andnot?:
./arch/arm64/include/asm/atomic_lse.h:35:15: error: expected string literal before ?ARM64_LSE_ATOMIC_INSN?
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op), \
...
./arch/arm64/include/asm/cmpxchg.h: In function ?__xchg_case_1?:
./arch/arm64/include/asm/cmpxchg.h:38:15: error: expected string literal before ?ARM64_LSE_ATOMIC_INSN?
asm volatile(ARM64_LSE_ATOMIC_INSN( \
--
Regards,
Artem
^ permalink raw reply
* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Bjorn Helgaas @ 2016-11-02 16:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161102160820.GA6568@bhelgaas-glaptop.roam.corp.google.com>
On Wed, Nov 02, 2016 at 11:08:20AM -0500, Bjorn Helgaas wrote:
> On Tue, Nov 01, 2016 at 07:06:31AM -0600, cov at codeaurora.org wrote:
> > Hi Bjorn,
> >
> > On 2016-10-31 15:48, Bjorn Helgaas wrote:
> > >On Wed, Sep 21, 2016 at 06:38:05PM -0400, Christopher Covington wrote:
> > >>The Qualcomm Technologies QDF2432 SoC does not support accesses
> > >>smaller
> > >>than 32 bits to the PCI configuration space. Register the appropriate
> > >>quirk.
> > >>
> > >>Signed-off-by: Christopher Covington <cov@codeaurora.org>
> > >
> > >Hi Christopher,
> > >
> > >Can you rebase this against v4.9-rc1? It no longer applies to my tree.
> >
> > I apologize for not being clearer. This patch depends on:
> >
> > PCI/ACPI: Extend pci_mcfg_lookup() responsibilities
> > PCI/ACPI: Check platform-specific ECAM quirks
> >
> > These patches from Tomasz Nowicki were previously in your pci/ecam-v6
> > branch, but that seems to have come and gone. How would you like to
> > proceed?
>
> Oh yes, that's right, I forgot that connection. I'm afraid I kind of
> dropped the ball on that thread, so I went back and read through it
> again.
>
> I *think* the current state is:
>
> - I'm OK with the first two patches that add the quirk
> infrastructure.
>
> - My issue with the last three patches that add ThunderX quirks is
> that there's no generic description of the ECAM address space.
>
> So if I understand correctly, your Qualcomm patch depends only on the
> first two patches.
I put those first two patches and yours on pci/ecam-v6 and pushed it
again, so you can check it out.
Bjorn
^ permalink raw reply
* flush_dcache_page() in ARM vs ARM64
From: Catalin Marinas @ 2016-11-02 16:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161102132714.GA1326@lnxartpec.se.axis.com>
On Wed, Nov 02, 2016 at 02:27:14PM +0100, Rabin Vincent wrote:
> ARMv7-A and ARMv8-A are, as far as I can see, identical in which cache
> behaviours they support. The data cache has to behave as PIPT while for
> the instruction cache, PIPT, VIPT, and ASIC-tagged VIVT behaviours are
> supported. See section B3.11 of the ARMv7-A ARM and section D4.9 of the
> ARMv8-A ARM.
>
> Both ARMv7-A with Multiprocessing Extensions and ARMv8-A broadcast cache
> maintenance operations to other cores. See B2.2.5 of the ARMv7-A ARM
> and D7.2.57 of the ARMv8-A ARM.
>
> Both arch/arm/ (for ARMv6+) and arch/arm64/ define PG_arch_1 to be
> PG_dcache_clean and use it to postpone flushing from flush_dcache_page()
> to set_pte_at(). See arch/{arm,arm64}/mm/flush.c.
>
> However, arch/arm64/'s flush_dcache_page() is implemented like this:
>
> void flush_dcache_page(struct page *page)
> {
> if (test_bit(PG_dcache_clean, &page->flags))
> clear_bit(PG_dcache_clean, &page->flags);
> }
arm64 had a similar implementation to arm until commit b5b6c9e9149d
("arm64: Avoid cache flushing in flush_dcache_page()").
> Why does arch/arm/ flush the data cache area in flush_dcache_page() for
> the (!mapping || page_mapcount(page)) case even on ARMv7+ME, while
> arch/arm64/ doesn't for ARMv8?
IIRC, the reason was D-cache aliases which have disappeared from ARMv7.
> Why does arch/arm/ invalidate the instruction cache in
> flush_dcache_page() for the (mapping && page_count(page)) case even for
> ARMv7+ME, while arch/arm64/ doesn't for ARMv8?
I guess no-one updated it for non-aliasing caches.
> What would break with the following patch?
>
> diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
> index 3cced84..f1e6190 100644
> --- a/arch/arm/mm/flush.c
> +++ b/arch/arm/mm/flush.c
> @@ -327,6 +327,12 @@ void flush_dcache_page(struct page *page)
> if (page == ZERO_PAGE(0))
> return;
>
> + if (!cache_ops_need_broadcast() && cache_is_vipt_nonaliasing()) {
> + if (test_bit(PG_dcache_clean, &page->flags))
> + clear_bit(PG_dcache_clean, &page->flags);
> + return;
> + }
> +
> mapping = page_mapping(page);
>
> if (!cache_ops_need_broadcast() &&
This should work. Note that the test_bit() is just an optimisation I
borrowed from powerpc, not sure it has any noticeable impact (you could
as well just do the clear_bit()).
--
Catalin
^ permalink raw reply
* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Sinan Kaya @ 2016-11-02 16:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161102160820.GA6568@bhelgaas-glaptop.roam.corp.google.com>
Hi Bjorn,
On 11/2/2016 12:08 PM, Bjorn Helgaas wrote:
> On Tue, Nov 01, 2016 at 07:06:31AM -0600, cov at codeaurora.org wrote:
>> Hi Bjorn,
>>
>> On 2016-10-31 15:48, Bjorn Helgaas wrote:
>>> On Wed, Sep 21, 2016 at 06:38:05PM -0400, Christopher Covington wrote:
>>>> The Qualcomm Technologies QDF2432 SoC does not support accesses
>>>> smaller
>>>> than 32 bits to the PCI configuration space. Register the appropriate
>>>> quirk.
>>>>
>>>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
>>>
>>> Hi Christopher,
>>>
>>> Can you rebase this against v4.9-rc1? It no longer applies to my tree.
>>
>> I apologize for not being clearer. This patch depends on:
>>
>> PCI/ACPI: Extend pci_mcfg_lookup() responsibilities
>> PCI/ACPI: Check platform-specific ECAM quirks
>>
>> These patches from Tomasz Nowicki were previously in your pci/ecam-v6
>> branch, but that seems to have come and gone. How would you like to
>> proceed?
>
> Oh yes, that's right, I forgot that connection. I'm afraid I kind of
> dropped the ball on that thread, so I went back and read through it
> again.
>
> I *think* the current state is:
>
> - I'm OK with the first two patches that add the quirk
> infrastructure.
>
> - My issue with the last three patches that add ThunderX quirks is
> that there's no generic description of the ECAM address space.
>
> So if I understand correctly, your Qualcomm patch depends only on the
> first two patches.
>
> Then the question is how the Qualcomm ECAM address space is described.
> Your quirk overrides the default pci_generic_ecam_ops with the
> &pci_32b_ops, but it doesn't touch the address space part, so I assume
> the bus ranges and corresponding address space in your MCFG is
> correct. So far, so good.
Qualcomm ECAM space includes both the root port and the endpoint address
space with a single contiguous 256 MB address space described in MCFG table.
There is no need to describe additional resources like PNP0C02.
The only thing we missed was 8/16 bits access support on the root port.
That's why, we need Cov's patch.
>
> Is there also an ACPI device that contains that space in _CRS? I
> think we concluded that the standard solution is to describe this with
> a PNP0C02 device.
>
> Would you mind opening a bugzilla at bugzilla.kernel.org and attaching
> the dmesg log, /proc/iomem, and maybe a DSDT dump? I'd like to have
> something to point at to say "if you need an MCFG quirk, you need the
> MCFG bit and *also* these other related ACPI device bits, and here's
> how it should be done."
>
> Bjorn
>
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH v7 0/7] arm/arm64: vgic: Implement API for vGICv3 live migration
From: Christoffer Dall @ 2016-11-02 16:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMJs5B8aLZCDeAVhJN7Cajt4PL4HBtXc3BiNzMyjK1tOSjMwmg@mail.gmail.com>
Hi Vijay,
On Thu, Oct 06, 2016 at 02:14:13PM +0200, Christoffer Dall wrote:
> Hi Vijay,
>
> On Wed, Oct 5, 2016 at 4:33 PM, Vijay Kilari <vijay.kilari@gmail.com> wrote:
> > Hi Marc, Christoffer,
> >
> > Do you have any review comments on this patch set?.
> >
> Since we missed the 4.9 merge window there is no urgency just yet, and
> I'm tied up with other things for a while, and Marc is away this week
> on holiday. I'm sure he'll have a look when he's back and I'll follow
> up later.
>
I think it would be useful for you to post a v7 of your patch set
rebased v4.9-rcX and addressing the issue you found yourself with a
wrong parameter.
Then I'll have another look.
Thanks,
-Christoffer
^ permalink raw reply
* [PATCH] coresight: Add support for ARM Coresight STM-500
From: Suzuki K Poulose @ 2016-11-02 16:19 UTC (permalink / raw)
To: linux-arm-kernel
Add the PIDs for STM-500 to the known STM devices list.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Chunyan Zhang <zhang.chunyan@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
drivers/hwtracing/coresight/coresight-stm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 49e0f1b..3524452 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -920,6 +920,11 @@ static struct amba_id stm_ids[] = {
.mask = 0x0003ffff,
.data = "STM32",
},
+ {
+ .id = 0x0003b963,
+ .mask = 0x0003ffff,
+ .data = "STM500",
+ },
{ 0, 0},
};
--
2.7.4
^ permalink raw reply related
* [PATCH v14 00/16] KVM PCIe/MSI passthrough on ARM/ARM64
From: Auger Eric @ 2016-11-02 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <452b773f-826b-61cd-55e3-018ecb34b503@arm.com>
Hi Robin,
On 24/10/2016 21:39, Robin Murphy wrote:
> On 21/10/16 10:26, Auger Eric wrote:
>> Hi Will,
>>
>> On 20/10/2016 19:32, Will Deacon wrote:
>>> Hi Eric,
>>>
>>> Thanks for posting this.
>>>
>>> On Wed, Oct 12, 2016 at 01:22:08PM +0000, Eric Auger wrote:
>>>> This is the second respin on top of Robin's series [1], addressing Alex' comments.
>>>>
>>>> Major changes are:
>>>> - MSI-doorbell API now is moved to DMA IOMMU API following Alex suggestion
>>>> to put all API pieces at the same place (so eventually in the IOMMU
>>>> subsystem)
>>>> - new iommu_domain_msi_resv struct and accessor through DOMAIN_ATTR_MSI_RESV
>>>> domain with mirror VFIO capability
>>>> - more robustness I think in the VFIO layer
>>>> - added "iommu/iova: fix __alloc_and_insert_iova_range" since with the current
>>>> code I failed allocating an IOVA page in a single page domain with upper part
>>>> reserved
>>>>
>>>> IOVA range exclusion will be handled in a separate series
>>>>
>>>> The priority really is to discuss and freeze the API and especially the MSI
>>>> doorbell's handling. Do we agree to put that in DMA IOMMU?
>>>>
>>>> Note: the size computation does not take into account possible page overlaps
>>>> between doorbells but it would add quite a lot of complexity i think.
>>>>
>>>> Tested on AMD Overdrive (single GICv2m frame) with I350 VF assignment.
>>>
>>> Marc, Robin and I sat down and had a look at the series and, whilst it's
>>> certainly addressing a problem that we desperately want to see fixed, we
>>> think that it's slightly over-engineering in places and could probably
>>> be simplified in the interest of getting something upstream that can be
>>> used as a base, on which the ABI can be extended as concrete use-cases
>>> become clear.
>>>
>>> Stepping back a minute, we're trying to reserve some of the VFIO virtual
>>> address space so that it can be used by devices to map their MSI doorbells
>>> using the SMMU. With your patches, this requires that (a) the kernel
>>> tells userspace about the size and alignment of the doorbell region
>>> (MSI_RESV) and (b) userspace tells the kernel the VA-range that can be
>>> used (RESERVED_MSI_IOVA).
>>>
>>> However, this is all special-cased for MSI doorbells and there are
>>> potentially other regions of the VFIO address space that are reserved
>>> and need to be communicated to userspace as well. We already know of
>>> hardware where the PCI RC intercepts p2p accesses before they make it
>>> to the SMMU, and other hardware where the MSI doorbell is at a fixed
>>> address. This means that we need a mechanism to communicate *fixed*
>>> regions of virtual address space that are reserved by VFIO. I don't
>>> even particularly care if VFIO_MAP_DMA enforces that, but we do need
>>> a way to tell userspace "hey, you don't want to put memory here because
>>> it won't work well with devices".
>>
>> I think we all agree on this. Exposing an API to the user space
>> reporting *fixed* reserved IOVA ranges is a requirement anyway. The
>> problem was quite clearly stated by Alex in
>> http://lkml.iu.edu/hypermail/linux/kernel/1610.0/03308.html
>> (VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE)
>>
>> I started working on this VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE
>> capability but to me and I think according to Alex, it was a different
>> API from MSI_RESV.
>>
>>>
>>> In that case, we end up with something like your MSI_RESV capability,
>>> but actually specifying a virtual address range that is simply not to
>>> be used by MAP_DMA -- we don't say anything about MSIs. Now, taking this
>>> to its logical conclusion, we no longer need to distinguish between
>>> remappable reserved regions and fixed reserved regions in the ABI.
>>> Instead, we can have the kernel allocate the virtual address space for
>>> the remappable reserved regions (probably somewhere in the bottom 4GB)
>>> and expose them via the capability.
>>
>>
>> If I understand correctly you want the host to arbitrarily choose where
>> it puts the iovas reserved for MSI and not ask the userspace.
>>
>> Well so we are back to the discussions we had in Dec 2015 (see Marc's
>> answer in http://thread.gmane.org/gmane.comp.emulators.kvm.arm.devel/3858).
>
> To an extent, yes, however the difference is that we now know we
> definitely have to deal with situations in which userspace *cannot* be
> in total control of the memory map, and that changes the game:
>
> _________
> / \
> / Fixed \
> / things (A) \
> ( _________ )
> \ / MSI \ /
> X doorbells X
> / \___(B)___/ \
> ( )
> \ Remappable /
> \ things (C)/
> \_________/
>
> In the absence of A, then B == C so it was very hard to not want to
> implement C. As soon as A *has* to be implemented for other reasons,
> then that is also sufficient to encompass B. C can still be implemented
> later as a nice-to-have, but is not necessary to get B off the ground.
>
>> - So I guess you will init an iova_domain seomewhere below the 4GB to
>> allocate the MSIs. what size are you going to choose. Don't you have the
>> same need to dimension the iova range.
>> - we still need to assess the MSI assignment safety. How will we compute
>> safety for VFIO?
>
> Absolutely. We're talking in general terms of the userspace ABI here,
> although that can't help but colour the underlying implementation
> decisions.
Sorry for the delay I was out of the office last week.
The userspace ABI to retrieve reserved regions is the *easy* part. It is
based on VFIO capability chain and I have an RFC ready.
Of course the VFIO internals still have to handle the
> specific case of MSIs, but that's basically no more than this:
>
> static bool msi_isolation = true; /* until proven otherwise */
> static unsigned long msi_remap_virt_base = 0x08000000; /* fits QEMU */
> static size_t msi_remap_size;
>
> vfio_msi_thing_callback(thing) {
> msi_remap_size += thing->info.size;
> msi_isolation &= thing->info.flags & PROVIDES_ISOLATION;
> }
>
> vfio_msi_init(...) {
> ...
> #ifdef CONFIG_X86
> msi_remap_virt_base = 0xfee00000;
> msi_remap_size = 0x100000;
> msi_isolation = irq_remapping_enabled;
> #else
> irq_for_each_msi_thing(vfio_msi_thing_callback);
> #endif
> ...
> }
>
> vfio_attach_group(...) {
> ...
> if (!msi_isolation && !allow_unsafe_interrupts)
> return -ENOWAY;
> ...
> get_msi_region_cookie(domain, msi_remap_base, msi_remap_size);
> ...
> }
I doubt Alex will accept to put that code in VFIO. He suggested in the
past to use the IOMMU API to retrieve the reserved region(s).
what about adding a reserved_regions list in iommu_domain and add a new
iommu_ops, something like
void add_reserved_regions(struct iommu_domain *, struct device *dev)
whose role would be to populate the list. This add_reserved_regions()
would be called on __iommu_attach_device. The list would be emptied on
iommu_domain_free().
arm-smmu cb implementation would be in charge of
- computing non ACS PCI host bridge windows from @dev,
- computing msi_rebase_map/size computation
on x86, cb would simply populate the MSI window.
vfio would lookup the iommu domain reserved_regions list on
VFIO_IOMMU_GET_INFO
Drawback of this approach is the security aspect is not handled by the
IOMMU API.
Note that combining v14 series and this one would implement everything I
think + giving the flexibility for the userspace to choose where it put
things. But well, LPC discussions will bring the last word obviously.
>
> And when a well-behaved userspace queries the reserved regions, that
> base address and size is just one of potentially several that it should
> get back. It's that "querying the reserved regions" bit that needs to be
> gotten right first time.
>
> Note that at this point I'm no longer even overly bothered about the
> details of irq_for_each_msi_thing(), as it's an internal kernel
> interface and thus malleable, although obviously the simpler the better.
> I have to say Punit's idea of iterating irq_domains does actually look
> really neat and tidy as a proof-of-concept, and also makes me think off
> on a tangent that it would be sweet to be able to retrieve base+size
> from dev->msi_domain to pre-allocate MSI pages in default domains, and
> obviate the compose 'failure' case.
As Punit mentionned, the natural place where the msi doorbell base,
size and irq_remapping can be retrieved looks to be the irqchip itself.
It works perfectly fine for v2m and its. Hence my first attempt to use a
cb at this level (irqchip msi_doorbell_info up to v11).
Adding a cb at irq_domain level looks quite impractical to me to
retrieve the info. Actually I don't see how to manage that without
adding new fields in irq_domain struct. If you have any suggestion,
please let me know.
Thanks
Eric
>
>> This simplifies things in the
>>> following ways:
>>>
>>> * You don't need to keep track of MSI vs DMA addresses in the VFIO rbtree
>> right: I guess you rely on iommu_map to return an error in case the iova
>> is already mapped somewhere else.
>>> * You don't need to try collapsing doorbells into a single region
>> why? at host level I guess you will init a single iova domain?
>
> Yeah, right now this one goes either way - as things stand, it does make
> life easier on the host side to make a single region to hang off the
> back of the current iova_cookie magic, and as illustrated above it's
> possibly the most trivial part of the whole thing, but the point is we
> still don't *need* to. Since a userspace ABI for generic reservations
> has to be able handle more than one region for the sake of non-MSI
> things, we'd be free to change the kernel-side implementation in future
> to just report multiple doorbells as individual regions - for starters,
> if and when we add dynamic reservations and userspace gets to pick its
> own IOVAs for those, it'll be a damn sight easier *not* to coalesce
> everything.
>
>>> * You don't need a special MAP flavour to map MSI doorbells
>> right
>>> * The ABI is reusable for PCI p2p and fixed doorbells
>> right
>>
>> Aren't we moving the issue at user-space? Currently QEMU mach-virt
>> address space is fully static. Adapting mach-virt to adjust to host
>> constraints is not straightforward. It is simple to reject the
>> assignment in case of collision but more difficult to react positively.
>
> The point is that we *have* to move at least some of the issue to
> userspace, and by then I'm struggling to see any real difference between
> these situations:
>
> a) QEMU asks VFIO to map some pages for DMA, gets an error back because
> VFIO detects it conflicts with a reserved region, and gives up.
> b) QEMU starts by asking VFIO what regions are reserved, realises they
> will overlap with its hard-coded RAM address, and gives up.
>
> where (a) requires a bunch of kernel machinery to second-guess
> userspace, while (b) simply relies on userspace not being broken. And if
> userspace fails at not being broken, then we simply retain the behaviour
> which actually happens right now:
>
> c) QEMU maps some pages for DMA at the same address as PCI config space
> on the underlying hardware. Hilarity ensues.
>
> Of course, userspace could be anything other than QEMU as well, so it's
> not necessarily second-guessable at all; maybe we make the arbitrary
> msi_remap_virt_base a VFIO module parameter to be more accommodating.
> Who knows, maybe it turns out that's enough to keep users happy and we
> never need to implement fully dynamic reservations.
>
> Robin.
>
>>> I really think it would make your patch series both generally useful and
>>> an awful lot smaller, whilst leaving the door open to ABI extension on
>>> a case-by-case basis when we determine that it's really needed.
>>
>> I would like to have a better understanding of how you assess the
>> security and dimension the iova domain. This is the purpose of msi
>> doorbell registration, which is not neat at all I acknowledge but well I
>> did not find any other solution and did not get any other suggestion.
>> Besides I think the per-cpu thing is over-engineered and this can
>> definitively be simplified.
>>
>> VFIO part was reviewed by Alex and I don't have the impression that this
>> is the blocking part. besides there is on iova.c fix,
>> IOMMU_CAP_INTR_REMAP removal; so is it really over-complicated?
>>
>> Thanks
>>
>> Eric
>>
>>>
>>> Thoughts?
>>>
>>> Will
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>
>>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* [PATCH] ARM: DT: stm32: move dma translation to board files
From: Alexandre Torgue @ 2016-11-02 16:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAF3+TqeiPjtG7Fs1-cpbcHGxxtSS1UOGD=S=sggpaZahFLJhEQ@mail.gmail.com>
On 11/02/2016 05:07 PM, Bruno Herrera wrote:
> Hi
>
> On Wed, Nov 2, 2016 at 12:32 PM, Alexandre Torgue
> <alexandre.torgue@st.com> wrote:
>> Hi
>>
>> On 10/31/2016 07:58 PM, Rados?aw Pietrzyk wrote:
>>>
>>> I think wlcore driver searches dma-ranges in its parent that's why sdio
>>> node needs it.
>>
>>
>> Yes I agree. In this case it is needed as you have subnode in sdio node.
>> So IMO empty dma-ranges could be removed from ethernet and usb node, but
>> kept in future sdio subnode.
>
> Now it is clear.
Nice. Can I add your tested-by ?
>
>>
>> Bruno,
>> Do you plan to push sdio support ?
>
> Yes I do, but I'm not sure how long it will take. The I had to
> change(and hack) the mmci code because I could not get the ID from
> STM32 SDIO IP.
> My current WIP is at @
> https://github.com/mcoquelin-stm32/afboot-stm32/pull/4#issuecomment-247571615
> I know Andrea Merello is also working on that (and he probably has a
> more complete patch).
>
>>
>>
>>
>>>
>>> 2016-10-31 17:41 GMT+01:00 Bruno Herrera <bruherrera@gmail.com
>>> <mailto:bruherrera@gmail.com>>:
>>>
>>> On Mon, Oct 31, 2016 at 12:14 PM, Rados?aw Pietrzyk
>>> <radoslaw.pietrzyk at gmail.com <mailto:radoslaw.pietrzyk@gmail.com>>
>>> wrote:
>>> > This is weird because dma ddresses are recalculated using parent's
>>> > dma-ranges property and soc already has it so there should be
>>> absolutely no
>>> > problem.
>>>
>>> These are my DTS and DTSI file.
>>> >
>>> > 2016-10-31 11:27 GMT+01:00 Bruno Herrera <bruherrera@gmail.com
>>> <mailto:bruherrera@gmail.com>>:
>>> >>
>>> >> On Fri, Oct 28, 2016 at 5:09 AM, Rados?aw Pietrzyk
>>> >> <radoslaw.pietrzyk@gmail.com
>>> <mailto:radoslaw.pietrzyk@gmail.com>> wrote:
>>> >> > Have you defined your sdio node within soc node ?
>>> >>
>>> >> It is in the SOC node of the DSTI file.
>>> >>
>>> >> >
>>> >> > 2016-10-27 14:57 GMT+02:00 Bruno Herrera <bruherrera@gmail.com
>>> <mailto:bruherrera@gmail.com>>:
>>> >> >>
>>> >> >> Hi Alex,
>>> >> >>
>>> >> >> On Thu, Oct 27, 2016 at 10:21 AM, Alexandre Torgue
>>> >> >> <alexandre.torgue at st.com <mailto:alexandre.torgue@st.com>>
>>> wrote:
>>> >> >> > Hi Bruno,
>>> >> >> >
>>> >> >> >
>>> >> >> > On 10/27/2016 12:43 PM, Bruno Herrera wrote:
>>> >> >> >>
>>> >> >> >> Hi Alex,
>>> >> >> >>
>>> >> >> >> On Wed, Oct 26, 2016 at 7:09 AM, Alexandre Torgue
>>> >> >> >> <alexandre.torgue at st.com <mailto:alexandre.torgue@st.com>>
>>> wrote:
>>> >> >> >>>
>>> >> >> >>> Hi Bruno,
>>> >> >> >>>
>>> >> >> >>> On 10/25/2016 11:06 PM, Bruno Herrera wrote:
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>> Hi Alexandre,
>>> >> >> >>>>
>>> >> >> >>>>>
>>> >> >> >>>>> stm32f469-disco and stm32f429-eval boards use SDRAM
>>> start address
>>> >> >> >>>>> remapping
>>> >> >> >>>>> (to @0) to boost performances. A DMA translation through
>>> >> >> >>>>> "dma-ranges"
>>> >> >> >>>>> property was needed for other masters than the M4 CPU.
>>> >> >> >>>>> stm32f429-disco doesn't use remapping so doesn't need
>>> this DMA
>>> >> >> >>>>> translation.
>>> >> >> >>>>> This patches moves this DMA translation definition from
>>> stm32f429
>>> >> >> >>>>> soc
>>> >> >> >>>>> file
>>> >> >> >>>>> to board files.
>>> >> >> >>>>>
>>> >> >> >>>>> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com
>>> <mailto:alexandre.torgue@st.com>>
>>>
>>> >> >> >>>>>
>>> >> >> >>>>> diff --git a/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>>> b/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>>> index 13c7cd2..a763c15 100644
>>> >> >> >>>>> --- a/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>>> +++ b/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>>> @@ -82,6 +82,10 @@
>>> >> >> >>>>> };
>>> >> >> >>>>> };
>>> >> >> >>>>>
>>> >> >> >>>>> + soc {
>>> >> >> >>>>> + dma-ranges = <0xc0000000 0x0 0x10000000>;
>>> >> >> >>>>> + };
>>> >> >> >>>>> +
>>> >> >> >>>>> usbotg_hs_phy: usbphy {
>>> >> >> >>>>> #phy-cells = <0>;
>>> >> >> >>>>> compatible = "usb-nop-xceiv";
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>> Shouldn't also the peripheral dma-ranges property move to
>>> board
>>> >> >> >>>> specific
>>> >> >> >>>> too?
>>> >> >> >>>> I had this patch for while but I didn't had the time to
>>> submit:
>>> >> >> >>>
>>> >> >> >>>
>>> >> >> >>>
>>> >> >> >>> Well spot I forgot it. Actually, discussing with Arnd
>>> ysterday on
>>> >> >> >>> IIRC,
>>> >> >> >>> empty dma-ranges is not needed. Can you test on your side by
>>> >> >> >>> removing
>>> >> >> >>> dma-ranges in usb node please ?
>>> >> >> >>
>>> >> >> >> Unfortunately will take a time for me to set up this
>>> environment on
>>> >> >> >> the STM32F4-EVAL board.
>>> >> >> >> And on the discovery boards we dont have this scenario.
>>> That was the
>>> >> >> >> main reason I did not submit the patch right away.
>>> >> >> >> My conclusion and I might be wrong but is based on the my
>>> tests with
>>> >> >> >> SDIO device at STM32F469I-DISCO board.
>>> >> >> >>
>>> >> >> >> I started this issue as discussion at ST Forum but Maxime
>>> gave me
>>> >> >> >> the
>>> >> >> >> hint.
>>> >> >> >>
>>> >> >> >>
>>> >> >> >>
>>> >> >> >>
>>> >> >> >>
>>>
>>> https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fDMA2%20and%20SYSCFG_MEMRMP%20relationship&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=44
>>>
>>> <https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fDMA2%20and%20SYSCFG_MEMRMP%20relationship&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=44>
>>> >> >> >>
>>> >> >> >>> I will push a v2 by removing empty dma-ranges if tests are
>>> ok in
>>> >> >> >>> your
>>> >> >> >>> side.
>>> >> >> >>
>>> >> >> >>
>>> >> >> >> From my understating/conclusion is: when empty
>>> property(dma-ranges)
>>> >> >> >> is
>>> >> >> >> the device node, the mapping will be taken in consideration
>>> when
>>> >> >> >> using
>>> >> >> >> DMA otherwise the mapping is ignored.
>>> >> >> >> And in the SDIO case it is needed for DEV->MEM(SDRAM) and
>>> >> >> >> MEM(SDRAM)->DEV. If it is not the case for the devices in
>>> question
>>> >> >> >> so
>>> >> >> >> I suppose it can work without the property.
>>> >> >> >
>>> >> >> >
>>> >> >> > For sure translation has to be done but I'm not sure that an
>>> empty
>>> >> >> > "dma-ranges" is needed in device node to activate it. For
>>> Ethernet
>>> >> >> > empty
>>> >> >> > "dma-ranges" is not needed. I will try with usb.
>>> >> >>
>>> >> >> In the case of SDIO it is needed. As example this is my
>>> working SDIO
>>> >> >> node:
>>> >> >>
>>> >> >> sdio: sdio at 40012c00 {
>>> >> >> compatible = "arm,pl18x", "arm,primecell";
>>> >> >> arm,primecell-periphid = <0x00480181>;
>>> >> >> reg = <0x40012c00 0x400>;
>>> >> >> dmas = <&dma2 6 4 0x10400 0x3>, /* Logical - DevToMem */
>>> >> >> <&dma2 3 4 0x10400 0x3>; /* Logical - MemToDev */
>>> >> >> dma-names = "rx", "tx";
>>> >> >> clocks = <&rcc 0 171>;
>>> >> >> clock-names = "apb_pclk";
>>> >> >> interrupts = <49>;
>>> >> >> status = "disabled";
>>> >> >> };
>>> >> >>
>>> >> >> &sdio {
>>> >> >> status = "okay";
>>> >> >> vmmc-supply = <&wlan_en>;
>>> >> >> bus-width = <4>;
>>> >> >> max-frequency = <24000000>;
>>> >> >> pinctrl-names = "default";
>>> >> >> pinctrl-0 = <&sdio_pins>;
>>> >> >> ti,non-removable;
>>> >> >> ti,needs-special-hs-handling;
>>> >> >> dma-ranges;
>>> >> >> cap-power-off-card;
>>> >> >> keep-power-in-suspend;
>>> >> >>
>>> >> >> #address-cells = <1>;
>>> >> >> #size-cells = <0>;
>>> >> >> wlcore: wlcore at 0 {
>>> >> >> compatible = "ti,wl1835";
>>> >> >> reg = <2>;
>>> >> >> interrupt-parent = <&gpioa>;
>>> >> >> interrupts = <8 IRQ_TYPE_EDGE_RISING>;
>>> >> >> };
>>> >> >> };
>>> >> >>
>>> >> >> >
>>> >> >> > alex
>>> >> >> >
>>> >> >> >
>>> >> >> >>
>>> >> >> >>>
>>> >> >> >>> Thanks in advance
>>> >> >> >>> Alex
>>> >> >> >>>
>>> >> >> >>>
>>> >> >> >>>>
>>> >> >> >>>> Author: Bruno Herrera <bruherrera@gmail.com
>>> <mailto:bruherrera@gmail.com>>
>>>
>>> >> >> >>>> Date: Sun Oct 16 14:50:00 2016 -0200
>>> >> >> >>>>
>>> >> >> >>>> ARM: DT: STM32: Use dma-ranges property per board not
>>> at dtsi
>>> >> >> >>>> file
>>> >> >> >>>>
>>> >> >> >>>> diff --git a/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>> b/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>> index 6bfc595..2a22a82 100644
>>> >> >> >>>> --- a/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>> +++ b/arch/arm/boot/dts/stm32429i-eval.dts
>>> >> >> >>>> @@ -52,6 +52,10 @@
>>> >> >> >>>> model = "STMicroelectronics STM32429i-EVAL board";
>>> >> >> >>>> compatible = "st,stm32429i-eval", "st,stm32f429";
>>> >> >> >>>>
>>> >> >> >>>> + soc {
>>> >> >> >>>> + dma-ranges = <0xC0000000 0x0 0x10000000>;
>>> >> >> >>>> + };
>>> >> >> >>>> +
>>> >> >> >>>> chosen {
>>> >> >> >>>> bootargs = "root=/dev/ram rdinit=/linuxrc";
>>> >> >> >>>> stdout-path = "serial0:115200n8";
>>> >> >> >>>> @@ -96,6 +100,7 @@
>>> >> >> >>>>
>>> >> >> >>>> ðernet0 {
>>> >> >> >>>> status = "okay";
>>> >> >> >>>> + dma-ranges;
>>> >> >> >>>> pinctrl-0 = <ðernet0_mii>;
>>> >> >> >>>> pinctrl-names = "default";
>>> >> >> >>>> phy-mode = "mii-id";
>>> >> >> >>>> @@ -116,6 +121,7 @@
>>> >> >> >>>> };
>>> >> >> >>>>
>>> >> >> >>>> &usbotg_hs {
>>> >> >> >>>> + dma-ranges;
>>> >> >> >>>> dr_mode = "host";
>>> >> >> >>>> phys = <&usbotg_hs_phy>;
>>> >> >> >>>> phy-names = "usb2-phy";
>>> >> >> >>>> diff --git a/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>> b/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>> index 7d624a2..697a133 100644
>>> >> >> >>>> --- a/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>> +++ b/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>> @@ -59,7 +59,6 @@
>>> >> >> >>>> };
>>> >> >> >>>>
>>> >> >> >>>> soc {
>>> >> >> >>>> - dma-ranges = <0xc0000000 0x0 0x10000000>;
>>> >> >> >>>>
>>> >> >> >>>> timer2: timer at 40000000 {
>>> >> >> >>>> compatible = "st,stm32-timer";
>>> >> >> >>>> @@ -472,13 +471,11 @@
>>> >> >> >>>> st,syscon = <&syscfg 0x4>;
>>> >> >> >>>> snps,pbl = <8>;
>>> >> >> >>>> snps,mixed-burst;
>>> >> >> >>>> - dma-ranges;
>>> >> >> >>>> status = "disabled";
>>> >> >> >>>> };
>>> >> >> >>>>
>>> >> >> >>>> usbotg_hs: usb at 40040000 {
>>> >> >> >>>> compatible = "snps,dwc2";
>>> >> >> >>>> - dma-ranges;
>>> >> >> >>>> reg = <0x40040000 0x40000>;
>>> >> >> >>>> interrupts = <77>;
>>> >> >> >>>> clocks = <&rcc 0 29>;
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>> diff --git a/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>>> b/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>>> index 0596d60..3a1cfdd 100644
>>> >> >> >>>>> --- a/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>>> +++ b/arch/arm/boot/dts/stm32f429.dtsi
>>> >> >> >>>>> @@ -59,8 +59,6 @@
>>> >> >> >>>>> };
>>> >> >> >>>>>
>>> >> >> >>>>> soc {
>>> >> >> >>>>> - dma-ranges = <0xc0000000 0x0 0x10000000>;
>>> >> >> >>>>> -
>>> >> >> >>>>> timer2: timer at 40000000 {
>>> >> >> >>>>> compatible = "st,stm32-timer";
>>> >> >> >>>>> reg = <0x40000000 0x400>;
>>> >> >> >>>>> diff --git a/arch/arm/boot/dts/stm32f469-disco.dts
>>> >> >> >>>>> b/arch/arm/boot/dts/stm32f469-disco.dts
>>> >> >> >>>>> index 9e73656..c2213c0 100644
>>> >> >> >>>>> --- a/arch/arm/boot/dts/stm32f469-disco.dts
>>> >> >> >>>>> +++ b/arch/arm/boot/dts/stm32f469-disco.dts
>>> >> >> >>>>> @@ -64,6 +64,10 @@
>>> >> >> >>>>> aliases {
>>> >> >> >>>>> serial0 = &usart3;
>>> >> >> >>>>> };
>>> >> >> >>>>> +
>>> >> >> >>>>> + soc {
>>> >> >> >>>>> + dma-ranges = <0xc0000000 0x0 0x10000000>;
>>> >> >> >>>>> + };
>>> >> >> >>>>> };
>>> >> >> >>>>>
>>> >> >> >>>>> &clk_hse {
>>> >> >> >>>>> --
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>> Br.,
>>> >> >> >>>> Bruno
>>> >> >> >>>>
>>> >> >> >>>
>>> >> >> >
>>> >> >>
>>> >> >> _______________________________________________
>>> >> >> linux-arm-kernel mailing list
>>> >> >> linux-arm-kernel at lists.infradead.org
>>> <mailto:linux-arm-kernel@lists.infradead.org>
>>> >> >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>> <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>
>>> >> >
>>> >> >
>>> >
>>> >
>>>
>>>
>>
^ permalink raw reply
* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Bjorn Helgaas @ 2016-11-02 16:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <dbf40b73baa71155f39e13d6e51073aa@codeaurora.org>
On Tue, Nov 01, 2016 at 07:06:31AM -0600, cov at codeaurora.org wrote:
> Hi Bjorn,
>
> On 2016-10-31 15:48, Bjorn Helgaas wrote:
> >On Wed, Sep 21, 2016 at 06:38:05PM -0400, Christopher Covington wrote:
> >>The Qualcomm Technologies QDF2432 SoC does not support accesses
> >>smaller
> >>than 32 bits to the PCI configuration space. Register the appropriate
> >>quirk.
> >>
> >>Signed-off-by: Christopher Covington <cov@codeaurora.org>
> >
> >Hi Christopher,
> >
> >Can you rebase this against v4.9-rc1? It no longer applies to my tree.
>
> I apologize for not being clearer. This patch depends on:
>
> PCI/ACPI: Extend pci_mcfg_lookup() responsibilities
> PCI/ACPI: Check platform-specific ECAM quirks
>
> These patches from Tomasz Nowicki were previously in your pci/ecam-v6
> branch, but that seems to have come and gone. How would you like to
> proceed?
Oh yes, that's right, I forgot that connection. I'm afraid I kind of
dropped the ball on that thread, so I went back and read through it
again.
I *think* the current state is:
- I'm OK with the first two patches that add the quirk
infrastructure.
- My issue with the last three patches that add ThunderX quirks is
that there's no generic description of the ECAM address space.
So if I understand correctly, your Qualcomm patch depends only on the
first two patches.
Then the question is how the Qualcomm ECAM address space is described.
Your quirk overrides the default pci_generic_ecam_ops with the
&pci_32b_ops, but it doesn't touch the address space part, so I assume
the bus ranges and corresponding address space in your MCFG is
correct. So far, so good.
Is there also an ACPI device that contains that space in _CRS? I
think we concluded that the standard solution is to describe this with
a PNP0C02 device.
Would you mind opening a bugzilla at bugzilla.kernel.org and attaching
the dmesg log, /proc/iomem, and maybe a DSDT dump? I'd like to have
something to point at to say "if you need an MCFG quirk, you need the
MCFG bit and *also* these other related ACPI device bits, and here's
how it should be done."
Bjorn
^ 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