* [PATCH 1/5] dt-bindings: pinctrl: document the STMFX pinctrl bindings
From: Linus Walleij @ 2018-05-24 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <28c374e6-b440-f785-b371-03fe15c8bc4b@st.com>
On Fri, May 18, 2018 at 9:29 AM, Amelie DELAUNAY <amelie.delaunay@st.com> wrote:
> On 05/17/2018 08:36 AM, Lee Jones wrote:
>> On Wed, 16 May 2018, Amelie DELAUNAY wrote:
>>> On 05/16/2018 04:20 PM, Linus Walleij wrote:
>>>> On Wed, May 9, 2018 at 9:56 AM, Amelie DELAUNAY <amelie.delaunay@st.com> wrote:
>>>>
>>>>> Indeed, stmfx has other functions than GPIO. But, after comments done
>>>>> here: [1] and there: [2], it has been decided to move MFD parent/GPIO
>>>>> child drivers into a single PINCTRL/GPIO driver because of the following
>>>>> reasons:
>>>>> - Other stmfx functions (IDD measurement and TouchScreen controller) are
>>>>> not used on any of the boards using an stmfx and supported by Linux, so
>>>>> no way to test these functions, and no need to maintain them while they
>>>>> are not being used.
>>>>> - But, in the case a new board will use more than GPIO function on
>>>>> stmfx, the actual implementation allow to easily extract common init
>>>>> part of stmfx and put it in an MFD driver.
>>>>>
>>>>> So I could remove gpio sub-node and put its contents in stmfx node and
>>>>> keep single PINCTRL/GPIO driver for the time being.
>>>>> Please advise,
>>>>
>>>> I would normally advice to use the right modeling from the start, create
>>>> the MFD driver and spawn the devices from there. It is confusing
>>>> if the layout of the driver(s) doesn't really match the layout of the
>>>> hardware.
>>>>
>>>> I understand that it is a pain to write new MFD drivers to get your
>>>> things going and it would be "nice to get this working really quick
>>>> now" but in my experience it is better to do it right from the start.
>>>>
>>>
>>> Hi Linus,
>>>
>>> Thanks for your advice. I understand the point.
>>> So, the right modeling would be to:
>>> - create an MFD driver with the common init part of stmfx
>>> - remove all common init part of stmfx-pinctrl driver and keep only all
>>> gpio/pinctrl functions.
>>>
>>> I will not develop the other stmfx functions (IDD measurement driver and
>>> TouchScreen controller driver) because, as explained ealier, they are
>>> not used on any of the boards using an stmfx and supported by Linux, so
>>> no way to test these functions, and no need to maintain them while they
>>> are not being used.
>>>
>>> Lee, are you OK with that ?
>>
>> I missed a lot of this conversation I think, but from what I've read,
>> it sounds fine.
>>
>
> I summarize the situation:
> - I still don't have an official datasheet for STMFX device which could
> justify the use of an MFD driver;
> - the MFD driver will contain the STMFX chip initialization stuff such
> as regmap initialization (regmap structure will be shared with the
> child), chip initialization, global interrupt management;
> - there will be only one child (GPIO/PINCTRL node) for the time being.
But there will be more devices in it. And they will invariably be put
to use later, and there will be new versions of the chip as well, and
then you will be happy about doing the MFD core, which makes it
easy to add new variants with different subdevices.
> So, is "MFD driver + GPIO/PINCTRL driver" the right modeling, and does
> it still sound fine after this summary ? :)
No I think it should use an MFD core.
Mainly because of device tree concerns.
The main reason is that the device tree bindings will be different if
you add an MFD core later, the GPIO and pinctrl driver will
move to a child node, making old device trees incompatible.
We could have a single driver in GPIO+pin control if it is a child
of an MFD node in the device tree, but it doesn't make much
sense as the I2C device need to be probing to the MFD core.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH V4 0/8] net: ethernet: stmmac: add support for stm32mp1
From: Alexandre Torgue @ 2018-05-24 7:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180523.160811.1425159248399846750.davem@davemloft.net>
On 05/23/2018 10:08 PM, David Miller wrote:
> From: Christophe Roullier <christophe.roullier@st.com>
> Date: Wed, 23 May 2018 17:47:51 +0200
>
>> Patches to have Ethernet support on stm32mp1
>> Changelog:
>> Remark from Rob Herring
>> Move Documentation/devicetree/bindings/arm/stm32.txt in
>> Documentation/devicetree/bindings/arm/stm32/stm32.txt and create
>> Documentation/devicetree/bindings/arm/stm32/stm32-syscon.txt
>>
>> Replace also in arch/arm/boot/dts/stm32mp157c.dtsi, syscfg: system-config at 50020000
>> with syscfg: syscon at 50020000syscfg: system-config at 50020000
>
> Probably the DTS file updates need to go in via the ARM tree, not
> mine.
Yes I will take them in my tree
>
> Can you respin a net-next targetted series that has just the driver
> code and device tree binding updates?
>
> Thank you!
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH V4 1/8] net: ethernet: stmmac: add adaptation for stm32mp157c.
From: Alexandre Torgue @ 2018-05-24 7:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527090479-5263-2-git-send-email-christophe.roullier@st.com>
Hi,
On 05/23/2018 05:47 PM, Christophe Roullier wrote:
> Glue codes to support stm32mp157c device and stay
> compatible with stm32 mcu family
>
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
Acked-by: Alexandre TORGUE <alexandre.torgue@st.com>
> drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 270 ++++++++++++++++++++--
> 1 file changed, 255 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> index 9e6db16..f51e327 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> @@ -16,49 +16,183 @@
> #include <linux/of_net.h>
> #include <linux/phy.h>
> #include <linux/platform_device.h>
> +#include <linux/pm_wakeirq.h>
> #include <linux/regmap.h>
> #include <linux/slab.h>
> #include <linux/stmmac.h>
>
> #include "stmmac_platform.h"
>
> -#define MII_PHY_SEL_MASK BIT(23)
> +#define SYSCFG_MCU_ETH_MASK BIT(23)
> +#define SYSCFG_MP1_ETH_MASK GENMASK(23, 16)
> +
> +#define SYSCFG_PMCR_ETH_CLK_SEL BIT(16)
> +#define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17)
> +#define SYSCFG_PMCR_ETH_SEL_MII BIT(20)
> +#define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21)
> +#define SYSCFG_PMCR_ETH_SEL_RMII BIT(23)
> +#define SYSCFG_PMCR_ETH_SEL_GMII 0
> +#define SYSCFG_MCU_ETH_SEL_MII 0
> +#define SYSCFG_MCU_ETH_SEL_RMII 1
>
> struct stm32_dwmac {
> struct clk *clk_tx;
> struct clk *clk_rx;
> + struct clk *clk_eth_ck;
> + struct clk *clk_ethstp;
> + struct clk *syscfg_clk;
> + bool int_phyclk; /* Clock from RCC to drive PHY */
> u32 mode_reg; /* MAC glue-logic mode register */
> struct regmap *regmap;
> u32 speed;
> + const struct stm32_ops *ops;
> + struct device *dev;
> +};
> +
> +struct stm32_ops {
> + int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
> + int (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare);
> + int (*suspend)(struct stm32_dwmac *dwmac);
> + void (*resume)(struct stm32_dwmac *dwmac);
> + int (*parse_data)(struct stm32_dwmac *dwmac,
> + struct device *dev);
> + u32 syscfg_eth_mask;
> };
>
> static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
> {
> struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
> - u32 reg = dwmac->mode_reg;
> - u32 val;
> int ret;
>
> - val = (plat_dat->interface == PHY_INTERFACE_MODE_MII) ? 0 : 1;
> - ret = regmap_update_bits(dwmac->regmap, reg, MII_PHY_SEL_MASK, val);
> - if (ret)
> - return ret;
> + if (dwmac->ops->set_mode) {
> + ret = dwmac->ops->set_mode(plat_dat);
> + if (ret)
> + return ret;
> + }
>
> ret = clk_prepare_enable(dwmac->clk_tx);
> if (ret)
> return ret;
>
> - ret = clk_prepare_enable(dwmac->clk_rx);
> - if (ret)
> - clk_disable_unprepare(dwmac->clk_tx);
> + if (!dwmac->dev->power.is_suspended) {
> + ret = clk_prepare_enable(dwmac->clk_rx);
> + if (ret) {
> + clk_disable_unprepare(dwmac->clk_tx);
> + return ret;
> + }
> + }
> +
> + if (dwmac->ops->clk_prepare) {
> + ret = dwmac->ops->clk_prepare(dwmac, true);
> + if (ret) {
> + clk_disable_unprepare(dwmac->clk_rx);
> + clk_disable_unprepare(dwmac->clk_tx);
> + }
> + }
>
> return ret;
> }
>
> +static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare)
> +{
> + int ret = 0;
> +
> + if (prepare) {
> + ret = clk_prepare_enable(dwmac->syscfg_clk);
> + if (ret)
> + return ret;
> +
> + if (dwmac->int_phyclk) {
> + ret = clk_prepare_enable(dwmac->clk_eth_ck);
> + if (ret) {
> + clk_disable_unprepare(dwmac->syscfg_clk);
> + return ret;
> + }
> + }
> + } else {
> + clk_disable_unprepare(dwmac->syscfg_clk);
> + if (dwmac->int_phyclk)
> + clk_disable_unprepare(dwmac->clk_eth_ck);
> + }
> + return ret;
> +}
> +
> +static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> +{
> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
> + u32 reg = dwmac->mode_reg;
> + int val;
> +
> + switch (plat_dat->interface) {
> + case PHY_INTERFACE_MODE_MII:
> + val = SYSCFG_PMCR_ETH_SEL_MII;
> + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
> + break;
> + case PHY_INTERFACE_MODE_GMII:
> + val = SYSCFG_PMCR_ETH_SEL_GMII;
> + if (dwmac->int_phyclk)
> + val |= SYSCFG_PMCR_ETH_CLK_SEL;
> + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
> + break;
> + case PHY_INTERFACE_MODE_RMII:
> + val = SYSCFG_PMCR_ETH_SEL_RMII;
> + if (dwmac->int_phyclk)
> + val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
> + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
> + break;
> + case PHY_INTERFACE_MODE_RGMII:
> + case PHY_INTERFACE_MODE_RGMII_ID:
> + case PHY_INTERFACE_MODE_RGMII_RXID:
> + case PHY_INTERFACE_MODE_RGMII_TXID:
> + val = SYSCFG_PMCR_ETH_SEL_RGMII;
> + if (dwmac->int_phyclk)
> + val |= SYSCFG_PMCR_ETH_CLK_SEL;
> + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
> + break;
> + default:
> + pr_debug("SYSCFG init : Do not manage %d interface\n",
> + plat_dat->interface);
> + /* Do not manage others interfaces */
> + return -EINVAL;
> + }
> +
> + return regmap_update_bits(dwmac->regmap, reg,
> + dwmac->ops->syscfg_eth_mask, val);
> +}
> +
> +static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
> +{
> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
> + u32 reg = dwmac->mode_reg;
> + int val;
> +
> + switch (plat_dat->interface) {
> + case PHY_INTERFACE_MODE_MII:
> + val = SYSCFG_MCU_ETH_SEL_MII;
> + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
> + break;
> + case PHY_INTERFACE_MODE_RMII:
> + val = SYSCFG_MCU_ETH_SEL_RMII;
> + pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
> + break;
> + default:
> + pr_debug("SYSCFG init : Do not manage %d interface\n",
> + plat_dat->interface);
> + /* Do not manage others interfaces */
> + return -EINVAL;
> + }
> +
> + return regmap_update_bits(dwmac->regmap, reg,
> + dwmac->ops->syscfg_eth_mask, val);
> +}
> +
> static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
> {
> clk_disable_unprepare(dwmac->clk_tx);
> clk_disable_unprepare(dwmac->clk_rx);
> +
> + if (dwmac->ops->clk_prepare)
> + dwmac->ops->clk_prepare(dwmac, false);
> }
>
> static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
> @@ -70,15 +204,22 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
> /* Get TX/RX clocks */
> dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx");
> if (IS_ERR(dwmac->clk_tx)) {
> - dev_err(dev, "No tx clock provided...\n");
> + dev_err(dev, "No ETH Tx clock provided...\n");
> return PTR_ERR(dwmac->clk_tx);
> }
> +
> dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx");
> if (IS_ERR(dwmac->clk_rx)) {
> - dev_err(dev, "No rx clock provided...\n");
> + dev_err(dev, "No ETH Rx clock provided...\n");
> return PTR_ERR(dwmac->clk_rx);
> }
>
> + if (dwmac->ops->parse_data) {
> + err = dwmac->ops->parse_data(dwmac, dev);
> + if (err)
> + return err;
> + }
> +
> /* Get mode register */
> dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
> if (IS_ERR(dwmac->regmap))
> @@ -91,11 +232,46 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
> return err;
> }
>
> +static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
> + struct device *dev)
> +{
> + struct device_node *np = dev->of_node;
> +
> + dwmac->int_phyclk = of_property_read_bool(np, "st,int-phyclk");
> +
> + /* Check if internal clk from RCC selected */
> + if (dwmac->int_phyclk) {
> + /* Get ETH_CLK clocks */
> + dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck");
> + if (IS_ERR(dwmac->clk_eth_ck)) {
> + dev_err(dev, "No ETH CK clock provided...\n");
> + return PTR_ERR(dwmac->clk_eth_ck);
> + }
> + }
> +
> + /* Clock used for low power mode */
> + dwmac->clk_ethstp = devm_clk_get(dev, "ethstp");
> + if (IS_ERR(dwmac->clk_ethstp)) {
> + dev_err(dev, "No ETH peripheral clock provided for CStop mode ...\n");
> + return PTR_ERR(dwmac->clk_ethstp);
> + }
> +
> + /* Clock for sysconfig */
> + dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk");
> + if (IS_ERR(dwmac->syscfg_clk)) {
> + dev_err(dev, "No syscfg clock provided...\n");
> + return PTR_ERR(dwmac->syscfg_clk);
> + }
> +
> + return 0;
> +}
> +
> static int stm32_dwmac_probe(struct platform_device *pdev)
> {
> struct plat_stmmacenet_data *plat_dat;
> struct stmmac_resources stmmac_res;
> struct stm32_dwmac *dwmac;
> + const struct stm32_ops *data;
> int ret;
>
> ret = stmmac_get_platform_resources(pdev, &stmmac_res);
> @@ -112,6 +288,16 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
> goto err_remove_config_dt;
> }
>
> + data = of_device_get_match_data(&pdev->dev);
> + if (!data) {
> + dev_err(&pdev->dev, "no of match data provided\n");
> + ret = -EINVAL;
> + goto err_remove_config_dt;
> + }
> +
> + dwmac->ops = data;
> + dwmac->dev = &pdev->dev;
> +
> ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
> if (ret) {
> dev_err(&pdev->dev, "Unable to parse OF data\n");
> @@ -149,15 +335,48 @@ static int stm32_dwmac_remove(struct platform_device *pdev)
> return ret;
> }
>
> +static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
> +{
> + int ret = 0;
> +
> + ret = clk_prepare_enable(dwmac->clk_ethstp);
> + if (ret)
> + return ret;
> +
> + clk_disable_unprepare(dwmac->clk_tx);
> + clk_disable_unprepare(dwmac->syscfg_clk);
> + if (dwmac->int_phyclk)
> + clk_disable_unprepare(dwmac->clk_eth_ck);
> +
> + return ret;
> +}
> +
> +static void stm32mp1_resume(struct stm32_dwmac *dwmac)
> +{
> + clk_disable_unprepare(dwmac->clk_ethstp);
> +}
> +
> +static int stm32mcu_suspend(struct stm32_dwmac *dwmac)
> +{
> + clk_disable_unprepare(dwmac->clk_tx);
> + clk_disable_unprepare(dwmac->clk_rx);
> +
> + return 0;
> +}
> +
> #ifdef CONFIG_PM_SLEEP
> static int stm32_dwmac_suspend(struct device *dev)
> {
> struct net_device *ndev = dev_get_drvdata(dev);
> struct stmmac_priv *priv = netdev_priv(ndev);
> + struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
> +
> int ret;
>
> ret = stmmac_suspend(dev);
> - stm32_dwmac_clk_disable(priv->plat->bsp_priv);
> +
> + if (dwmac->ops->suspend)
> + ret = dwmac->ops->suspend(dwmac);
>
> return ret;
> }
> @@ -166,8 +385,12 @@ static int stm32_dwmac_resume(struct device *dev)
> {
> struct net_device *ndev = dev_get_drvdata(dev);
> struct stmmac_priv *priv = netdev_priv(ndev);
> + struct stm32_dwmac *dwmac = priv->plat->bsp_priv;
> int ret;
>
> + if (dwmac->ops->resume)
> + dwmac->ops->resume(dwmac);
> +
> ret = stm32_dwmac_init(priv->plat);
> if (ret)
> return ret;
> @@ -181,8 +404,24 @@ static int stm32_dwmac_resume(struct device *dev)
> static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
> stm32_dwmac_suspend, stm32_dwmac_resume);
>
> +static struct stm32_ops stm32mcu_dwmac_data = {
> + .set_mode = stm32mcu_set_mode,
> + .suspend = stm32mcu_suspend,
> + .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
> +};
> +
> +static struct stm32_ops stm32mp1_dwmac_data = {
> + .set_mode = stm32mp1_set_mode,
> + .clk_prepare = stm32mp1_clk_prepare,
> + .suspend = stm32mp1_suspend,
> + .resume = stm32mp1_resume,
> + .parse_data = stm32mp1_parse_data,
> + .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK
> +};
> +
> static const struct of_device_id stm32_dwmac_match[] = {
> - { .compatible = "st,stm32-dwmac"},
> + { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
> + { .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
> { }
> };
> MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
> @@ -199,5 +438,6 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
> module_platform_driver(stm32_dwmac_driver);
>
> MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>");
> -MODULE_DESCRIPTION("STMicroelectronics MCU DWMAC Specific Glue layer");
> +MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>");
> +MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer");
> MODULE_LICENSE("GPL v2");
>
^ permalink raw reply
* [PATCH v2] ARM: pxa: dts: add pin definitions for extended GPIOs
From: Robert Jarzmik @ 2018-05-24 7:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522202232.7981-1-daniel@zonque.org>
Daniel Mack <daniel@zonque.org> writes:
> The PXA3xx series features some extended GPIO banks which are named GPIO0_2,
> GPIO1_2 etc. The PXA300, PXA310 and PXA320 have different numbers of such
> pins, and they also have variant-specific register offsets.
>
> Signed-off-by: Daniel Mack <daniel@zonque.org>
Applied to pxa/dt, thanks.
Cheers.
--
Robert
^ permalink raw reply
* [PATCH v4] pinctrl: msm: fix gpio-hog related boot issues
From: Linus Walleij @ 2018-05-24 7:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3016198.WsLn1iDyWJ@debian64>
On Sat, May 19, 2018 at 11:52 AM, Christian Lamparter
<chunkeey@gmail.com> wrote:
> On Friday, May 18, 2018 7:18:26 AM CEST Bjorn Andersson wrote:
>> > + gpio-ranges = <&msmgpio 0 0 150>;
>>
>> I'm still confused to why this information is in DT at all, it feels
>> like an implementation detail, not a system configuration thing.
This reflects especially the layout of systems such as HiSilicon
that have a standard fit-all pin controller (pinctrl-single.c, shared
with OMAP) and a standard PL061 GPIO primecell from ARM
(gpio-pl061.c) shared with many other SoCs.
These are non-HiSilicon-specific drivers used in other SoCs.
So the ranges in e.g. arch/arm64/boot/dts/hisilicon/hi6220.dtsi
define how the pin controller and the GPIO blocks inside the
SoC are connected using these ranges.
So "system configuration" is something different for you guys
than for HiSilicon. They need to configure how the stuff inside
the SoC are wired up, because they are using standard silicon
used in other SoCs.
As I understand it, your SoCs are so Qualcomm-specific and
idiomatic that this situation never happened to you :)
> I did look at the commits and code from back in 2013. From what
> I can gather "this implementation detail" was realized the way
> it is now, because "devicetree was the new thing" and it seemed
> like a good idea to make it as extendable/generic as possible.
Many mistakes were made when shoehorning device tree
into the ARM architecture with one finger constantly on the
fast-forward button. There were reasons for this. Mea culpa.
I hope to fix them all before I retire.
One use case (which still applied) are pin controllers and GPIO
chips defined through the use of platform data.
If we have for example a PCI card with a pin controller and
GPIO block (Alessandro Rubini ran into such a device at
CERN IIRC) we need to be able to define both components
and connect them using ranges, even without either
device tree or ACPI hardware descriptions.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v9 3/4] arm64: Implement page table free interfaces
From: Chintan Pandya @ 2018-05-24 7:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180523140157.GG26965@arm.com>
On 5/23/2018 7:31 PM, Will Deacon wrote:
> Hi Chintan,
Hi Will,
>
> [as a side note: I'm confused on the status of this patch series, as part
> of it was reposted separately by Toshi. Please can you work together?]
I will share all 4 patches once again as v10 and take latest version of
1/4 as updated by Toshi.
>
> On Mon, Apr 30, 2018 at 01:11:33PM +0530, Chintan Pandya wrote:
>> Implement pud_free_pmd_page() and pmd_free_pte_page().
>>
>> Implementation requires,
>> 1) Clearing off the current pud/pmd entry
>> 2) Invalidate TLB which could have previously
>> valid but not stale entry
>> 3) Freeing of the un-used next level page tables
>>
>> Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
>> ---
>> arch/arm64/mm/mmu.c | 29 +++++++++++++++++++++++++----
>> 1 file changed, 25 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>> index da98828..0f651db 100644
>> --- a/arch/arm64/mm/mmu.c
>> +++ b/arch/arm64/mm/mmu.c
>> @@ -45,6 +45,7 @@
>> #include <asm/memblock.h>
>> #include <asm/mmu_context.h>
>> #include <asm/ptdump.h>
>> +#include <asm/tlbflush.h>
>>
>> #define NO_BLOCK_MAPPINGS BIT(0)
>> #define NO_CONT_MAPPINGS BIT(1)
>> @@ -973,12 +974,32 @@ int pmd_clear_huge(pmd_t *pmdp)
>> return 1;
>> }
>>
>> -int pud_free_pmd_page(pud_t *pud, unsigned long addr)
>> +int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr)
>> {
>> - return pud_none(*pud);
>> + pmd_t *table;
>> +
>> + if (pmd_present(READ_ONCE(*pmdp))) {
>
> Might also be worth checking pmd_table here, just in case. (same for pud)
I had that check in v2 as below.
if (pud_val(*pud) && !pud_huge(*pud))
But removed that in v3 as unmap should change this to NONE if it is
not table. I still don't see the need of it.
>
>> + table = __va(pmd_val(*pmdp));
>
> Can you avoid dereferencing *pmdp twice, and instead READ_ONCE into a local
> variable, please? (same for pud)
Okay.
>
>> + pmd_clear(pmdp);
>> + __flush_tlb_kernel_pgtable(addr);
>> + free_page((unsigned long) table);
>
> Shouldn't this be pte_free_kernel, to pair with pte_alloc_kernel which
> was used to allocate the page in the first place? (similarly for pud)
Okay.
>
>> + }
>> + return 1;
>> }
>>
>> -int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
>> +int pud_free_pmd_page(pud_t *pudp, unsigned long addr)
>> {
>> - return pmd_none(*pmd);
>> + pmd_t *table;
>> + int i;
>> +
>> + if (pud_present(READ_ONCE(*pudp))) {
>> + table = __va(pud_val(*pudp));
>> + for (i = 0; i < PTRS_PER_PMD; i++)
>> + pmd_free_pte_page(&table[i], addr + (i * PMD_SIZE));
>
> I think it would be cleaner to write this as a do { ... } while, for
> consistency with the ioremap and vmalloc code.
Okay.
I'll raise v10 fixing above things. Thanks for the review.
>
> Will
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Chintan
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center,
Inc. is a member of the Code Aurora Forum, a Linux Foundation
Collaborative Project
^ permalink raw reply
* [PATCH v1 1/7] dt-bindings: pinctrl: add external interrupt support to MT7622 pinctrl
From: Linus Walleij @ 2018-05-24 7:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3898620ef606004aaddc332591ca467f56773029.1526835466.git.sean.wang@mediatek.com>
On Sun, May 20, 2018 at 7:01 PM, <sean.wang@mediatek.com> wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> Extend the capability of MT7622 pinctrl with adding EINT so that each
> GPIO can be used to notify CPU when a signal state is changing on the
> line as an external interrupt.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Patch applied with Rob's review tag.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v1 2/7] pinctrl: mediatek: refactor EINT related code for all MediaTek pinctrl can fit
From: Linus Walleij @ 2018-05-24 7:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7265772c758d4c56cabb95fda708550bc4d2fcb5.1526835466.git.sean.wang@mediatek.com>
On Sun, May 20, 2018 at 7:01 PM, <sean.wang@mediatek.com> wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> This patch is in preparation for adding EINT support to MT7622 pinctrl,
> and the refactoring doesn't alter any existent logic.
>
> A reason we have to refactor EINT code pieces into a generic way is that
> currently, they're tightly coupled with a certain type of MediaTek pinctrl
> would cause a grown in a very bad way as there is different types of
> pinctrl devices getting to join.
>
> Therefore, it is an essential or urgent thing that EINT code pieces are
> refactored to eliminate any dependencies across GPIO and EINT as possible.
>
> Additional structure mtk_eint_[xt, hw, regs] are being introduced for
> indicating how maps being designed between GPIO and EINT hw number, how to
> set and get GPIO state for a certain EINT pin, what characteristic on a
> EINT device is present on various SoCs.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v1 3/7] pinctrl: mediatek: add EINT support to MT7622 SoC
From: Linus Walleij @ 2018-05-24 7:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2d02c8e5c4c6b2f783ad55b887ce38d130be2a3f.1526835466.git.sean.wang@mediatek.com>
On Sun, May 20, 2018 at 7:01 PM, <sean.wang@mediatek.com> wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> Add EINT support to MT7622 SoC and the support is made as just an option
> to MT7622 pinctrl.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v1 4/7] pinctrl: mediatek: use generic EINT register maps for each SoC
From: Linus Walleij @ 2018-05-24 7:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <39738efefe94e3a4fb7668a27dd73ae49695dc3b.1526835466.git.sean.wang@mediatek.com>
On Sun, May 20, 2018 at 7:01 PM, <sean.wang@mediatek.com> wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> So far, EINT on each SoC all used exactly identical register map and thus
> it's better that we apply generic register map already supported in EINT
> library and stop copy-n-pasting the same data block and filling into its
> platform data.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v1 5/7] pinctrl: mediatek: remove unused fields in struct mtk_eint_hw
From: Linus Walleij @ 2018-05-24 7:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <72462fb7aab16463a42066998ac3b4bf35ada416.1526835466.git.sean.wang@mediatek.com>
On Sun, May 20, 2018 at 7:01 PM, <sean.wang@mediatek.com> wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> The .name field has been not being used in existent code logic, so
> it's better that we remove them all.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v1 6/7] MAINTAINERS: update entry for PIN CONTROLLER - MEDIATEK
From: Linus Walleij @ 2018-05-24 7:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e5bcfc9671a79fef4f38933bb04894f0f53b3d63.1526835466.git.sean.wang@mediatek.com>
On Sun, May 20, 2018 at 7:01 PM, <sean.wang@mediatek.com> wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> Add new files for the entry
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v1 7/7] arm64: dts: mt7622: add EINT support to pinctrl
From: Linus Walleij @ 2018-05-24 7:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f896f79ebfa9a262c89fdeed89cf086220ca051d.1526835466.git.sean.wang@mediatek.com>
On Sun, May 20, 2018 at 7:01 PM, <sean.wang@mediatek.com> wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> Add EINT support to pinctrl and set those GPIO keys as interrupt-driven
> keys.
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Please merge this through the ARM SoC tree.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2 4/7] Bluetooth: Add new quirk for non-persistent setup settings
From: Marcel Holtmann @ 2018-05-24 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527084544.4607.8.camel@mtkswgap22>
Hi Sean,
>>>>
>>>> [ ... ]
>>>>
>>>>>> - if (hci_dev_test_flag(hdev, HCI_SETUP)) {
>>>>>> + if (hci_dev_test_flag(hdev, HCI_SETUP) ||
>>>>>> + test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
>>>>>> hci_sock_dev_event(hdev, HCI_DEV_SETUP);
>>>>>
>>>>> I am not 100% sure that we want to send the HCI_DEV_SETUP event also multiple times. That is a userspace change that I would need to think about. We need to check create_monitor_event() and see what the btmon trace for this looks like. Can you send me a btmon -w trace.log when this change is active.
>>>>>
>>>>> Regards
>>>>>
>>>>> Marcel
>>>>>
>>>>
>>>> Sure, I'll send you the trace.log with the change is active.
>>>>
>>>> Sean
>>>>
>>>
>>>
>>> Attached trace.log was captured when I inputted commands power on and
>>> then off in bluetoothctl.
>>
>> the trace.log is somehow mangled. Something is not fully correct. Can you read it with btmon -r trace.log?
>>
>> Regards
>>
>> Marcel
>>
>
> Yes, I can read it with btmon -r trace.log.
>
> I post it as plain text as below
>
>
> Bluetooth monitor ver 5.37
> = Note: Linux version 4.16.0-rc1+ (aarch64) 0.641494
> = Note: Bluetooth subsystem version 2.22 0.641502
> = New Index: 00:00:46:76:22:01 (BR/EDR,UART,hci0) [hci0] 0.641505
> * Unknown packet (code 14 len 30) 0.641509
> 01 00 00 00 02 00 01 0e 00 01 00 00 00 10 62 6c ..............bl
> 75 65 74 6f 6f 74 68 64 00 00 00 00 00 00 uetoothd......
> * Unknown packet (code 14 len 30) 0.641592
> 02 00 00 00 02 00 01 0e 00 01 00 00 00 10 62 74 ..............bt
> 6d 6f 6e 00 00 00 00 00 00 00 00 00 00 00 mon...........
> * Unknown packet (code 16 len 7) [hci0] 6.536771
> 01 00 00 00 05 00 01 .......
> = Open Index: 00:00:46:76:22:01 [hci0] 6.717019
> = Index Info: 00:00:46:76:22:01 (MediaTek, Inc.) [hci0] 6.717030
can you try with the latest BlueZ 5.49 or git version. Seems it actually stumbles over the extra packet here. Fun fact is that I can not get a backtrace to pin-point the issue in btmon and why it crashes.
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.741093
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.742088
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.743102
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.744105
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.745109
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.746104
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.747097
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.748090
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.749078
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.750070
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.751061
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.752054
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.753046
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.754038
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.755031
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.756025
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.757013
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.758006
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.758999
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.759991
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.760983
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.761975
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.762963
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.763956
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.764948
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.765941
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.766933
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.767926
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.768919
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.769914
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.770909
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.771908
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.772904
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.773898
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.774892
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.775890
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.776882
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.777877
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.778871
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.779869
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.780864
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.781858
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.782852
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.783850
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.784845
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.785839
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.786833
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.787831
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.788826
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.789820
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.790814
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.791813
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.792809
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.793803
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.794798
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.795797
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.796791
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.797786
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.798779
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.799778
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.800774
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.801769
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.802763
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.803761
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.804755
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.805749
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.806743
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.807741
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.808737
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.809731
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.810725
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.811725
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.812719
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.813714
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.814708
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.815705
> 02 01 01 00 00 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.816378
> 02 01 01 00 00 .....
Why do I see only HCI events here? Is this event conveying any useful information. It is kinda complicated that this is 0xe4 event code which is actually reserved for future use by the Bluetooth SIG. Are there any accompanying HCI commands for this and they just not make it into btmon?
> < HCI Command: Vendor (0x3f|0x006f) plen 5 [hci0] 6.816413
> 01 07 01 00 04 .....
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 6.816536
> 02 07 01 00 00 .....
> < HCI Command: Vendor (0x3f|0x006f) plen 6 [hci0] 8.845071
> 01 06 02 00 00 01 ......
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 8.923456
> 02 06 01 00 00 .....
Here it looks like you have 0x006f opcode with first octet 0x01 for command and then vendor event 0xe4 with first octet 0x02 for event. I assume the second octet is then the vendor command code for these.
> < HCI Command: Reset (0x03|0x0003) plen 0 [hci0] 10.861118
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.865763
> Reset (0x03|0x0003) ncmd 1
> Status: Success (0x00)
> < HCI Command: Read Local Supported Fe.. (0x04|0x0003) plen 0 [hci0] 10.865805
>> HCI Event: Command Complete (0x0e) plen 12 [hci0] 10.865965
> Read Local Supported Features (0x04|0x0003) ncmd 1
> Status: Success (0x00)
> Features: 0xbf 0x3e 0x8d 0xfe 0xdb 0xff 0x7b 0x87
> 3 slot packets
> 5 slot packets
> Encryption
> Slot offset
> Timing accuracy
> Role switch
> Sniff mode
> Power control requests
> Channel quality driven data rate (CQDDR)
> SCO link
> HV2 packets
> HV3 packets
> CVSD synchronous data
> Power control
> Transparent synchronous data
> Broadcast Encryption
> Enhanced Data Rate ACL 2 Mbps mode
> Enhanced Data Rate ACL 3 Mbps mode
> Enhanced inquiry scan
> Interlaced inquiry scan
> Interlaced page scan
> RSSI with inquiry results
> Extended SCO link (EV3 packets)
> EV4 packets
> EV5 packets
> AFH capable slave
> AFH classification slave
> LE Supported (Controller)
> 3-slot Enhanced Data Rate ACL packets
> 5-slot Enhanced Data Rate ACL packets
> Sniff subrating
> Pause encryption
> AFH capable master
> AFH classification master
> Enhanced Data Rate eSCO 2 Mbps mode
> Enhanced Data Rate eSCO 3 Mbps mode
> 3-slot Enhanced Data Rate eSCO packets
> Extended Inquiry Response
> Simultaneous LE and BR/EDR (Controller)
> Secure Simple Pairing
> Encapsulated PDU
> Erroneous Data Reporting
> Non-flushable Packet Boundary Flag
> Link Supervision Timeout Changed Event
> Inquiry TX Power Level
> Enhanced Power Control
> Extended features
> < HCI Command: Read Local Version Info.. (0x04|0x0001) plen 0 [hci0] 10.865987
>> HCI Event: Vendor (0xff) plen 9 [hci0] 10.866259
> 29 19 09 17 20 48 07 11 00 )... H?
Is this meant to happen here?
>> HCI Event: Command Complete (0x0e) plen 12 [hci0] 10.866372
> Read Local Version Information (0x04|0x0001) ncmd 1
> Status: Success (0x00)
> HCI version: Bluetooth 4.2 (0x08) - Revision 4359 (0x1107)
> LMP version: Bluetooth 4.2 (0x08) - Subversion 2329 (0x0919)
> Manufacturer: MediaTek, Inc. (70)
> < HCI Command: Read BD ADDR (0x04|0x0009) plen 0 [hci0] 10.866391
>> HCI Event: Command Complete (0x0e) plen 10 [hci0] 10.866539
> Read BD ADDR (0x04|0x0009) ncmd 1
> Status: Success (0x00)
> Address: 00:00:46:76:22:01 (OLIVETTI NORTH AMERICA)
> < HCI Command: Read Buffer Size (0x04|0x0005) plen 0 [hci0] 10.866609
>> HCI Event: Command Complete (0x0e) plen 11 [hci0] 10.866754
> Read Buffer Size (0x04|0x0005) ncmd 1
> Status: Success (0x00)
> ACL MTU: 1021 ACL max packet: 8
> SCO MTU: 184 SCO max packet: 1
> < HCI Command: Read Class of Device (0x03|0x0023) plen 0 [hci0] 10.866775
>> HCI Event: Command Complete (0x0e) plen 7 [hci0] 10.866920
> Read Class of Device (0x03|0x0023) ncmd 1
> Status: Success (0x00)
> Class: 0x001f00
> Major class: Uncategorized, specific device code not specified
> Minor class: 0x00
> < HCI Command: Read Local Name (0x03|0x0014) plen 0 [hci0] 10.866939
>> HCI Event: Command Complete (0x0e) plen 252 [hci0] 10.867256
> Read Local Name (0x03|0x0014) ncmd 1
> Status: Success (0x00)
> Name: MTK MT7622 #1
> < HCI Command: Read Voice Setting (0x03|0x0025) plen 0 [hci0] 10.867308
>> HCI Event: Command Complete (0x0e) plen 6 [hci0] 10.867447
> Read Voice Setting (0x03|0x0025) ncmd 1
> Status: Success (0x00)
> Setting: 0x0060
> Input Coding: Linear
> Input Data Format: 2's complement
> Input Sample Size: 16-bit
> # of bits padding at MSB: 0
> Air Coding Format: CVSD
> < HCI Command: Read Number of Supporte.. (0x03|0x0038) plen 0 [hci0] 10.867474
>> HCI Event: Command Complete (0x0e) plen 5 [hci0] 10.867611
> Read Number of Supported IAC (0x03|0x0038) ncmd 1
> Status: Success (0x00)
> Number of IAC: 4
> < HCI Command: Read Current IAC LAP (0x03|0x0039) plen 0 [hci0] 10.867678
>> HCI Event: Command Complete (0x0e) plen 8 [hci0] 10.867865
> Read Current IAC LAP (0x03|0x0039) ncmd 1
> Status: Success (0x00)
> Number of IAC: 1
> Access code: 0x9e8b33 (General Inquiry)
> < HCI Command: Set Event Filter (0x03|0x0005) plen 1 [hci0] 10.867890
> Type: Clear All Filters (0x00)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.868033
> Set Event Filter (0x03|0x0005) ncmd 1
> Status: Success (0x00)
> < HCI Command: Write Connection Accept.. (0x03|0x0016) plen 2 [hci0] 10.868054
> Timeout: 20000.000 msec (0x7d00)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.868235
> Write Connection Accept Timeout (0x03|0x0016) ncmd 1
> Status: Success (0x00)
> < HCI Command: LE Read Buffer Size (0x08|0x0002) plen 0 [hci0] 10.868262
>> HCI Event: Command Complete (0x0e) plen 7 [hci0] 10.868392
> LE Read Buffer Size (0x08|0x0002) ncmd 1
> Status: Success (0x00)
> Data packet length: 251
> Num data packets: 8
> < HCI Command: LE Read Local Supported.. (0x08|0x0003) plen 0 [hci0] 10.868413
>> HCI Event: Command Complete (0x0e) plen 12 [hci0] 10.868587
> LE Read Local Supported Features (0x08|0x0003) ncmd 1
> Status: Success (0x00)
> Features: 0xfd 0x00 0x00 0x00 0x00 0x00 0x00 0x00
> LE Encryption
> Extended Reject Indication
> Slave-initiated Features Exchange
> LE Ping
> LE Data Packet Length Extension
> LL Privacy
> Extended Scanner Filter Policies
> < HCI Command: LE Read Supported States (0x08|0x001c) plen 0 [hci0] 10.868646
>> HCI Event: Command Complete (0x0e) plen 12 [hci0] 10.868787
> LE Read Supported States (0x08|0x001c) ncmd 1
> Status: Success (0x00)
> States: 0x000000001fffffff
> Non-connectable Advertising State
> Scannable Advertising State
> Connectable Advertising State
> High Duty Cycle Directed Advertising State
> Passive Scanning State
> Active Scanning State
> Initiating State
> and Connection State (Master Role)
> Connection State (Slave Role)
> Non-connectable Advertising State
> and Passive Scanning State
> Scannable Advertising State
> and Passive Scanning State
> Connectable Advertising State
> and Passive Scanning State
> High Duty Cycle Directed Advertising State
> and Passive Scanning State
> Non-connectable Advertising State
> and Active Scanning State
> Scannable Advertising State
> and Active Scanning State
> Connectable Advertising State
> and Active Scanning State
> High Duty Cycle Directed Advertising State
> and Active Scanning State
> Non-connectable Advertising State
> and Initiating State
> Scannable Advertising State
> and Initiating State
> Non-connectable Advertising State
> and Connection State (Master Role)
> Scannable Advertising State
> and Connection State (Master Role)
> Non-connectable Advertising State
> and Connection State (Slave Role)
> Scannable Advertising State
> and Connection State (Slave Role)
> Passive Scanning State
> and Initiating State
> Active Scanning State
> and Initiating State
> Passive Scanning State
> and Connection State (Master Role)
> Active Scanning State
> and Connection State (Master Role)
> Passive Scanning State
> and Connection State (Slave Role)
> Active Scanning State
> and Connection State (Slave Role)
> Initiating State
> and Connection State (Master Role)
> and Master Role & Master Role
> < HCI Command: Read Local Supported Co.. (0x04|0x0002) plen 0 [hci0] 10.868807
>> HCI Event: Command Complete (0x0e) plen 68 [hci0] 10.868985
> Read Local Supported Commands (0x04|0x0002) ncmd 1
> Status: Success (0x00)
> Commands: 176 entries
> Inquiry (Octet 0 - Bit 0)
> Inquiry Cancel (Octet 0 - Bit 1)
> Periodic Inquiry Mode (Octet 0 - Bit 2)
> Exit Periodic Inquiry Mode (Octet 0 - Bit 3)
> Create Connection (Octet 0 - Bit 4)
> Disconnect (Octet 0 - Bit 5)
> Add SCO Connection (Octet 0 - Bit 6)
> Create Connection Cancel (Octet 0 - Bit 7)
> Accept Connection Request (Octet 1 - Bit 0)
> Reject Connection Request (Octet 1 - Bit 1)
> Link Key Request Reply (Octet 1 - Bit 2)
> Link Key Request Negative Reply (Octet 1 - Bit 3)
> PIN Code Request Reply (Octet 1 - Bit 4)
> PIN Code Request Negative Reply (Octet 1 - Bit 5)
> Change Connection Packet Type (Octet 1 - Bit 6)
> Authentication Requested (Octet 1 - Bit 7)
> Set Connection Encryption (Octet 2 - Bit 0)
> Change Connection Link Key (Octet 2 - Bit 1)
> Master Link Key (Octet 2 - Bit 2)
> Remote Name Request (Octet 2 - Bit 3)
> Remote Name Request Cancel (Octet 2 - Bit 4)
> Read Remote Supported Features (Octet 2 - Bit 5)
> Read Remote Extended Features (Octet 2 - Bit 6)
> Read Remote Version Information (Octet 2 - Bit 7)
> Read Clock Offset (Octet 3 - Bit 0)
> Read LMP Handle (Octet 3 - Bit 1)
> Sniff Mode (Octet 4 - Bit 2)
> Exit Sniff Mode (Octet 4 - Bit 3)
> QoS Setup (Octet 4 - Bit 6)
> Role Discovery (Octet 4 - Bit 7)
> Switch Role (Octet 5 - Bit 0)
> Read Link Policy Settings (Octet 5 - Bit 1)
> Write Link Policy Settings (Octet 5 - Bit 2)
> Read Default Link Policy Settings (Octet 5 - Bit 3)
> Write Default Link Policy Settings (Octet 5 - Bit 4)
> Flow Specification (Octet 5 - Bit 5)
> Set Event Mask (Octet 5 - Bit 6)
> Reset (Octet 5 - Bit 7)
> Set Event Filter (Octet 6 - Bit 0)
> Flush (Octet 6 - Bit 1)
> Read PIN Type (Octet 6 - Bit 2)
> Write PIN Type (Octet 6 - Bit 3)
> Create New Unit Key (Octet 6 - Bit 4)
> Read Stored Link Key (Octet 6 - Bit 5)
> Write Stored Link Key (Octet 6 - Bit 6)
> Delete Stored Link Key (Octet 6 - Bit 7)
> Write Local Name (Octet 7 - Bit 0)
> Read Local Name (Octet 7 - Bit 1)
> Read Connection Accept Timeout (Octet 7 - Bit 2)
> Write Connection Accept Timeout (Octet 7 - Bit 3)
> Read Page Timeout (Octet 7 - Bit 4)
> Write Page Timeout (Octet 7 - Bit 5)
> Read Scan Enable (Octet 7 - Bit 6)
> Write Scan Enable (Octet 7 - Bit 7)
> Read Page Scan Activity (Octet 8 - Bit 0)
> Write Page Scan Activity (Octet 8 - Bit 1)
> Read Inquiry Scan Activity (Octet 8 - Bit 2)
> Write Inquiry Scan Activity (Octet 8 - Bit 3)
> Read Authentication Enable (Octet 8 - Bit 4)
> Write Authentication Enable (Octet 8 - Bit 5)
> Read Encryption Mode (Octet 8 - Bit 6)
> Write Encryption Mode (Octet 8 - Bit 7)
> Read Class of Device (Octet 9 - Bit 0)
> Write Class of Device (Octet 9 - Bit 1)
> Read Voice Setting (Octet 9 - Bit 2)
> Write Voice Setting (Octet 9 - Bit 3)
> Read Automatic Flush Timeout (Octet 9 - Bit 4)
> Write Automatic Flush Timeout (Octet 9 - Bit 5)
> Read Num Broadcast Retransmissions (Octet 9 - Bit 6)
> Write Num Broadcast Retransmissions (Octet 9 - Bit 7)
> Read Transmit Power Level (Octet 10 - Bit 2)
> Read Sync Flow Control Enable (Octet 10 - Bit 3)
> Write Sync Flow Control Enable (Octet 10 - Bit 4)
> Set Controller To Host Flow Control (Octet 10 - Bit 5)
> Host Buffer Size (Octet 10 - Bit 6)
> Host Number of Completed Packets (Octet 10 - Bit 7)
> Read Link Supervision Timeout (Octet 11 - Bit 0)
> Write Link Supervision Timeout (Octet 11 - Bit 1)
> Read Number of Supported IAC (Octet 11 - Bit 2)
> Read Current IAC LAP (Octet 11 - Bit 3)
> Write Current IAC LAP (Octet 11 - Bit 4)
> Read Page Scan Mode (Octet 11 - Bit 7)
> Write Page Scan Mode (Octet 12 - Bit 0)
> Set AFH Host Channel Classification (Octet 12 - Bit 1)
> Read Inquiry Scan Type (Octet 12 - Bit 4)
> Write Inquiry Scan Type (Octet 12 - Bit 5)
> Read Inquiry Mode (Octet 12 - Bit 6)
> Write Inquiry Mode (Octet 12 - Bit 7)
> Read Page Scan Type (Octet 13 - Bit 0)
> Write Page Scan Type (Octet 13 - Bit 1)
> Read AFH Channel Assessment Mode (Octet 13 - Bit 2)
> Write AFH Channel Assessment Mode (Octet 13 - Bit 3)
> Read Local Version Information (Octet 14 - Bit 3)
> Read Local Supported Features (Octet 14 - Bit 5)
> Read Local Extended Features (Octet 14 - Bit 6)
> Read Buffer Size (Octet 14 - Bit 7)
> Read Country Code (Octet 15 - Bit 0)
> Read BD ADDR (Octet 15 - Bit 1)
> Read Failed Contact Counter (Octet 15 - Bit 2)
> Reset Failed Contact Counter (Octet 15 - Bit 3)
> Read Link Quality (Octet 15 - Bit 4)
> Read RSSI (Octet 15 - Bit 5)
> Read AFH Channel Map (Octet 15 - Bit 6)
> Read Clock (Octet 15 - Bit 7)
> Read Loopback Mode (Octet 16 - Bit 0)
> Write Loopback Mode (Octet 16 - Bit 1)
> Enable Device Under Test Mode (Octet 16 - Bit 2)
> Setup Synchronous Connection (Octet 16 - Bit 3)
> Accept Synchronous Connection Request (Octet 16 - Bit 4)
> Reject Synchronous Connection Request (Octet 16 - Bit 5)
> Read Extended Inquiry Response (Octet 17 - Bit 0)
> Write Extended Inquiry Response (Octet 17 - Bit 1)
> Refresh Encryption Key (Octet 17 - Bit 2)
> Sniff Subrating (Octet 17 - Bit 4)
> Read Simple Pairing Mode (Octet 17 - Bit 5)
> Write Simple Pairing Mode (Octet 17 - Bit 6)
> Read Local OOB Data (Octet 17 - Bit 7)
> Read Inquiry Response TX Power Level (Octet 18 - Bit 0)
> Write Inquiry Transmit Power Level (Octet 18 - Bit 1)
> Read Default Erroneous Data Reporting (Octet 18 - Bit 2)
> Write Default Erroneous Data Reporting (Octet 18 - Bit 3)
> IO Capability Request Reply (Octet 18 - Bit 7)
> User Confirmation Request Reply (Octet 19 - Bit 0)
> User Confirmation Request Neg Reply (Octet 19 - Bit 1)
> User Passkey Request Reply (Octet 19 - Bit 2)
> User Passkey Request Negative Reply (Octet 19 - Bit 3)
> Remote OOB Data Request Reply (Octet 19 - Bit 4)
> Write Simple Pairing Debug Mode (Octet 19 - Bit 5)
> Enhanced Flush (Octet 19 - Bit 6)
> Remote OOB Data Request Neg Reply (Octet 19 - Bit 7)
> Send Keypress Notification (Octet 20 - Bit 2)
> IO Capability Request Negative Reply (Octet 20 - Bit 3)
> Read Encryption Key Size (Octet 20 - Bit 4)
> Set Event Mask Page 2 (Octet 22 - Bit 2)
> Read Enhanced Transmit Power Level (Octet 24 - Bit 0)
> Enhanced Setup Synchronous Connection (Octet 29 - Bit 3)
> Enhanced Accept Synchronous Connection Request (Octet 29 - Bit 4)
> Read Local Supported Codecs (Octet 29 - Bit 5)
> Set Triggered Clock Capture (Octet 30 - Bit 5)
> Truncated Page (Octet 30 - Bit 6)
> Truncated Page Cancel (Octet 30 - Bit 7)
> Set Connectionless Slave Broadcast (Octet 31 - Bit 0)
> Start Synchronization Train (Octet 31 - Bit 2)
> Set Reserved LT_ADDR (Octet 31 - Bit 4)
> Delete Reserved LT_ADDR (Octet 31 - Bit 5)
> Set Connectionless Slave Broadcast Data (Octet 31 - Bit 6)
> Read Synchronization Train Parameters (Octet 31 - Bit 7)
> Write Synchronization Train Parameters (Octet 32 - Bit 0)
> Remote OOB Extended Data Request Reply (Octet 32 - Bit 1)
> Read Authenticated Payload Timeout (Octet 32 - Bit 4)
> Write Authenticated Payload Timeout (Octet 32 - Bit 5)
> Read Local OOB Extended Data (Octet 32 - Bit 6)
> Write Secure Connections Test Mode (Octet 32 - Bit 7)
> Read Extended Page Timeout (Octet 33 - Bit 0)
> Write Extended Page Timeout (Octet 33 - Bit 1)
> Read Extended Inquiry Length (Octet 33 - Bit 2)
> Write Extended Inquiry Length (Octet 33 - Bit 3)
> LE Set Data Length (Octet 33 - Bit 6)
> LE Read Suggested Default Data Length (Octet 33 - Bit 7)
> LE Write Suggested Default Data Length (Octet 34 - Bit 0)
> LE Read Local P-256 Public Key (Octet 34 - Bit 1)
> LE Generate DHKey (Octet 34 - Bit 2)
> LE Add Device To Resolving List (Octet 34 - Bit 3)
> LE Remove Device From Resolving List (Octet 34 - Bit 4)
> LE Clear Resolving List (Octet 34 - Bit 5)
> LE Read Resolving List Size (Octet 34 - Bit 6)
> LE Read Peer Resolvable Address (Octet 34 - Bit 7)
> LE Read Local Resolvable Address (Octet 35 - Bit 0)
> LE Set Address Resolution Enable (Octet 35 - Bit 1)
> LE Set Resolvable Private Address Timeout (Octet 35 - Bit 2)
> LE Read Maximum Data Length (Octet 35 - Bit 3)
> Octet 35 - Bit 4
> Octet 35 - Bit 5
> Octet 35 - Bit 6
> Octet 35 - Bit 7
> Octet 36 - Bit 0
So you support the PHY commands, but do not indicate support LE 2M or LE Coded? Also these are Bluetooth 5.0 commands.
> < HCI Command: Write Simple Pairing Mode (0x03|0x0056) plen 1 [hci0] 10.869023
> Mode: Enabled (0x01)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.869185
> Write Simple Pairing Mode (0x03|0x0056) ncmd 1
> Status: Success (0x00)
> < HCI Command: Write Inquiry Mode (0x03|0x0045) plen 1 [hci0] 10.869239
> Mode: Inquiry Result with RSSI or Extended Inquiry Result (0x02)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.869371
> Write Inquiry Mode (0x03|0x0045) ncmd 1
> Status: Success (0x00)
> < HCI Command: Read Inquiry Response T.. (0x03|0x0058) plen 0 [hci0] 10.869396
>> HCI Event: Command Complete (0x0e) plen 5 [hci0] 10.869552
> Read Inquiry Response TX Power Level (0x03|0x0058) ncmd 1
> Status: Success (0x00)
> TX power: -1 dBm
> < HCI Command: Read Local Extended Fea.. (0x04|0x0004) plen 1 [hci0] 10.869572
> Page: 1
>> HCI Event: Command Complete (0x0e) plen 14 [hci0] 10.869729
> Read Local Extended Features (0x04|0x0004) ncmd 1
> Status: Success (0x00)
> Page: 1/2
> Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
> Secure Simple Pairing (Host Support)
> < HCI Command: Set Event Mask (0x03|0x0001) plen 8 [hci0] 10.869783
> Mask: 0x3dbff807fffbffff
> Inquiry Complete
> Inquiry Result
> Connection Complete
> Connection Request
> Disconnection Complete
> Authentication Complete
> Remote Name Request Complete
> Encryption Change
> Change Connection Link Key Complete
> Master Link Key Complete
> Read Remote Supported Features Complete
> Read Remote Version Information Complete
> QoS Setup Complete
> Command Complete
> Command Status
> Hardware Error
> Flush Occurred
> Role Change
> Mode Change
> Return Link Keys
> PIN Code Request
> Link Key Request
> Link Key Notification
> Loopback Command
> Data Buffer Overflow
> Max Slots Change
> Read Clock Offset Complete
> Connection Packet Type Changed
> QoS Violation
> Page Scan Mode Change
> Page Scan Repetition Mode Change
> Flow Specification Complete
> Inquiry Result with RSSI
> Read Remote Extended Features Complete
> Synchronous Connection Complete
> Synchronous Connection Changed
> Sniff Subrating
> Extended Inquiry Result
> Encryption Key Refresh Complete
> IO Capability Request
> IO Capability Request Reply
> User Confirmation Request
> User Passkey Request
> Remote OOB Data Request
> Simple Pairing Complete
> Link Supervision Timeout Changed
> Enhanced Flush Complete
> User Passkey Notification
> Keypress Notification
> Remote Host Supported Features Notification
> LE Meta
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.869921
> Set Event Mask (0x03|0x0001) ncmd 1
> Status: Success (0x00)
> < HCI Command: Read Stored Link Key (0x03|0x000d) plen 7 [hci0] 10.869947
> Address: 00:00:00:00:00:00 (OUI 00-00-00)
> Read all: 0x01
>> HCI Event: Command Complete (0x0e) plen 8 [hci0] 10.870129
> Read Stored Link Key (0x03|0x000d) ncmd 1
> Status: Success (0x00)
> Max num keys: 4
> Num keys: 0
> < HCI Command: Write Default Link Poli.. (0x02|0x000f) plen 2 [hci0] 10.870148
> Link policy: 0x0005
> Enable Role Switch
> Enable Sniff Mode
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.870310
> Write Default Link Policy Settings (0x02|0x000f) ncmd 1
> Status: Success (0x00)
> < HCI Command: Read Page Scan Activity (0x03|0x001b) plen 0 [hci0] 10.870331
>> HCI Event: Command Complete (0x0e) plen 8 [hci0] 10.870485
> Read Page Scan Activity (0x03|0x001b) ncmd 1
> Status: Success (0x00)
> Interval: 1280.000 msec (0x0800)
> Window: 11.250 msec (0x0012)
> < HCI Command: Read Page Scan Type (0x03|0x0046) plen 0 [hci0] 10.870504
>> HCI Event: Command Complete (0x0e) plen 5 [hci0] 10.870652
> Read Page Scan Type (0x03|0x0046) ncmd 1
> Status: Success (0x00)
> Type: Standard Scan (0x00)
> < HCI Command: LE Set Event Mask (0x08|0x0001) plen 8 [hci0] 10.870671
> Mask: 0x0000000000000980
> LE Read Local P-256 Public Key Complete
> LE Generate DHKey Complete
> Unknown mask (0x0000000000000800)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.870839
> LE Set Event Mask (0x08|0x0001) ncmd 1
> Status: Success (0x00)
> < HCI Command: Write LE Host Supported (0x03|0x006d) plen 2 [hci0] 10.870859
> Supported: 0x01
> Simultaneous: 0x00
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.871028
> Write LE Host Supported (0x03|0x006d) ncmd 1
> Status: Success (0x00)
> < HCI Command: Read Local Extended Fea.. (0x04|0x0004) plen 1 [hci0] 10.871059
> Page: 2
>> HCI Event: Command Complete (0x0e) plen 14 [hci0] 10.871201
> Read Local Extended Features (0x04|0x0004) ncmd 1
> Status: Success (0x00)
> Page: 2/2
> Features: 0x25 0x0b 0x00 0x00 0x00 0x00 0x00 0x00
> Connectionless Slave Broadcast - Master
> Synchronization Train
> Generalized interlaced scan
> Secure Connections (Controller Support)
> Ping
> Train nudging
> < HCI Command: Delete Stored Link Key (0x03|0x0012) plen 7 [hci0] 10.871240
> Address: 00:00:00:00:00:00 (OUI 00-00-00)
> Delete all: 0x01
>> HCI Event: Command Complete (0x0e) plen 6 [hci0] 10.871384
> Delete Stored Link Key (0x03|0x0012) ncmd 1
> Status: Success (0x00)
> Num keys: 0
> < HCI Command: Set Event Mask Page 2 (0x03|0x0063) plen 8 [hci0] 10.871403
> Mask: 0x0000000000b0c000
> Triggered Clock Capture
> Synchronization Train Complete
> Slave Page Response Timeout
> Connectionless Slave Broadcast Channel Map Change
> Authenticated Payload Timeout Expired
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.871566
> Set Event Mask Page 2 (0x03|0x0063) ncmd 1
> Status: Success (0x00)
> < HCI Command: Read Local Supported Co.. (0x04|0x000b) plen 0 [hci0] 10.871599
>> HCI Event: Command Complete (0x0e) plen 8 [hci0] 10.871750
> Read Local Supported Codecs (0x04|0x000b) ncmd 1
> Status: Success (0x00)
> Number of supported codecs: 2
> Codec: CVSD (0x02)
> Codec: Transparent (0x03)
> Number of vendor codecs: 0
> < HCI Command: Read Synchronization Tr.. (0x03|0x0077) plen 0 [hci0] 10.871769
>> HCI Event: Command Complete (0x0e) plen 11 [hci0] 10.871928
> Read Synchronization Train Parameters (0x03|0x0077) ncmd 1
> Status: Success (0x00)
> Interval: 0.000 msec (0x0000)
> Timeout: 0.000 msec (0x00000000)
> Service data: 0x00
> < HCI Command: Write Secure Connection.. (0x03|0x007a) plen 1 [hci0] 10.871947
> Support: Enabled (0x01)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.872098
> Write Secure Connections Host Support (0x03|0x007a) ncmd 1
> Status: Success (0x00)
> < HCI Command: Unknown (0x08|0x0031) plen 3 [hci0] 10.872156
> 03 00 00 ...
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.872322
> Unknown (0x08|0x0031) ncmd 1
> Status: Success (0x00)
> = Index Info: 00:00:46:76:22:01 (MediaTek, Inc.) [hci0] 10.872361
This extra index info worries me a little bit. I need to check if that is suppose to happen.
> < HCI Command: LE Set Scan Response D.. (0x08|0x0009) plen 32 [hci0] 10.872431
> Length: 10
> Name (complete): builder
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.872606
> LE Set Scan Response Data (0x08|0x0009) ncmd 1
> Status: Success (0x00)
> < HCI Command: Write Scan Enable (0x03|0x001a) plen 1 [hci0] 10.872627
> Scan enable: Page Scan (0x02)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.872819
> Write Scan Enable (0x03|0x001a) ncmd 1
> Status: Success (0x00)
> < HCI Command: Write Class of Device (0x03|0x0024) plen 3 [hci0] 10.872841
> Class: 0x000000
> Major class: Miscellaneous
> Minor class: 0x00
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.873036
> Write Class of Device (0x03|0x0024) ncmd 1
> Status: Success (0x00)
> * Unknown packet (code 17 len 9) [hci0] 10.873069
> 02 00 00 00 07 00 00 00 00 .........
> * Unknown packet (code 17 len 9) [hci0] 10.873069
> 01 00 00 00 07 00 00 00 00 .........
> < HCI Command: Write Local Name (0x03|0x0013) plen 248 [hci0] 10.873096
> Name: builder
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.873446
> Write Local Name (0x03|0x0013) ncmd 1
> Status: Success (0x00)
> < HCI Command: Write Extended Inquir.. (0x03|0x0052) plen 241 [hci0] 10.873470
> FEC: Not required (0x00)
> Name (complete): builder
> TX power: -1 dBm
> Device ID: USB Implementer's Forum assigned (0x0002)
> Vendor: Linux Foundation (0x1d6b)
> Product: 0x0246
> Version: 5.2.11 (0x052b)
> 16-bit Service UUIDs (complete): 4 entries
> Generic Access Profile (0x1800)
> Generic Attribute Profile (0x1801)
> A/V Remote Control (0x110e)
> A/V Remote Control Target (0x110c)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 10.873857
> Write Extended Inquiry Response (0x03|0x0052) ncmd 1
> Status: Success (0x00)
> * Unknown packet (code 17 len 13) [hci0] 10.873903
> 01 00 00 00 01 00 05 00 00 d1 0a 00 00 .............
> * Unknown packet (code 17 len 10) [hci0] 10.873913
> 02 00 00 00 06 00 d1 0a 00 00 ..........
> * Unknown packet (code 16 len 7) [hci0] 17.803939
> 01 00 00 00 05 00 00 .......
> < HCI Command: Write Scan Enable (0x03|0x001a) plen 1 [hci0] 17.803983
> Scan enable: No Scans (0x00)
>> HCI Event: Command Complete (0x0e) plen 4 [hci0] 17.804233
> Write Scan Enable (0x03|0x001a) ncmd 1
> Status: Success (0x00)
> < HCI Command: Vendor (0x3f|0x006f) plen 6 [hci0] 17.804282
> 01 06 02 00 00 00 ......
>> HCI Event: Unknown (0xe4) plen 5 [hci0] 17.804636
> 02 06 01 00 00 .....
> * Unknown packet (code 17 len 13) [hci0] 17.811580
> 01 00 00 00 01 00 05 00 00 d0 0a 00 00 .............
> * Unknown packet (code 17 len 10) [hci0] 17.811596
> 02 00 00 00 06 00 d0 0a 00 00 ..........
> = Close Index: 00:00:46:76:22:01 [hci0] 17.811625
Regards
Marcel
^ permalink raw reply
* [PATCH v12 0/8] Clock for CPU scaling support for msm8996
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
[v12]
* Addressed the kbuild fail on arm architecture
[v11]
* Split the series into domains
[v9]
* Addressed comments from Viresh and Russel about the error handling
[v8]
* Reordered the patch series into 4 groups
* Addressed comments from Amit about the comments and commit messages
* Addressed comments from Amit and Viresh about the resourses deallocation
[v7]
* Addressed comments from Viresh about resourses deallocation
and DT compatible
[v6]
* Addressed comments from Viresh about:
** Comments style
** Kconfig bool instead of tristate
** DT and documentation style
** Resourses deallocation on an error
** Typos
[v5]
* Rebased
* Addressed comments from Bjorn about SPDX style,
functions and parameters naming
* Addressed comments from Viresh DT properties and style, comments style,
resourses deallocation, documentation placement
* Addressed comments from Sricharan about unnessesary include
* Addressed comments from Nicolas
* Addressed comments from Rob about the commit messages and acks
* Addressed comments from Mark
[v4]
* Adressed all comments from Stephen
* Added CPU regulator support
* Added qcom-cpufreq-kryo driver
[v3]
* Rebased on top of the latest PLL driver changes
* Addressed comment from Rob Herring for bindings
[v2]
* Addressed comments from Rob Herring for bindings
* Addressed comments from Mark Rutland for memory barrier
* Addressed comments from Julien Thierry for clock reenabling condition
* Tuned the HW configuration for clock frequencies below 600MHz
SOC (1/15):
Extracts the kryo l2 accessors driver from the QCOM PMU driver
Clocks (2/15-9/15):
This series adds support for the CPU clocks on msm8996 devices.
The driver uses the existing PLL drivers and is required to control
the CPU frequency scaling on the MSM8996.
Ilia Lin (6):
soc: qcom: Separate kryo l2 accessors from PMU driver
clk: Use devm_ in the register fixed factor clock
clk: qcom: Add CPU clock driver for msm8996
dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
clk: qcom: cpu-8996: Add support to switch below 600Mhz
clk: qcom: Add ACD path to CPU clock driver for msm8996
Rajendra Nayak (2):
clk: qcom: Make clk_alpha_pll_configure available to modules
clk: qcom: cpu-8996: Add support to switch to alternate PLL
.../devicetree/bindings/clock/qcom,kryocc.txt | 17 +
drivers/clk/clk-fixed-factor.c | 2 +-
drivers/clk/qcom/Kconfig | 10 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/clk-alpha-pll.c | 1 +
drivers/clk/qcom/clk-alpha-pll.h | 6 +
drivers/clk/qcom/clk-cpu-8996.c | 510 +++++++++++++++++++++
drivers/perf/Kconfig | 1 +
drivers/perf/qcom_l2_pmu.c | 90 +---
drivers/soc/qcom/Kconfig | 3 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/kryo-l2-accessors.c | 56 +++
include/soc/qcom/kryo-l2-accessors.h | 12 +
13 files changed, 643 insertions(+), 67 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
create mode 100644 include/soc/qcom/kryo-l2-accessors.h
--
1.9.1
^ permalink raw reply
* [PATCH v12 1/8] soc: qcom: Separate kryo l2 accessors from PMU driver
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
The driver provides kernel level API for other drivers
to access the MSM8996 L2 cache registers.
Separating the L2 access code from the PMU driver and
making it public to allow other drivers use it.
The accesses must be separated with a single spinlock,
maintained in this driver.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/perf/Kconfig | 1 +
drivers/perf/qcom_l2_pmu.c | 90 ++++++++++--------------------------
drivers/soc/qcom/Kconfig | 3 ++
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/kryo-l2-accessors.c | 56 ++++++++++++++++++++++
include/soc/qcom/kryo-l2-accessors.h | 12 +++++
6 files changed, 97 insertions(+), 66 deletions(-)
create mode 100644 drivers/soc/qcom/kryo-l2-accessors.c
create mode 100644 include/soc/qcom/kryo-l2-accessors.h
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..561252a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -69,6 +69,7 @@ config HISI_PMU
config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI
+ select QCOM_KRYO_L2_ACCESSORS
help
Provides support for the L2 cache performance monitor unit (PMU)
in Qualcomm Technologies processors.
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 842135c..cc31f51 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -31,6 +31,7 @@
#include <asm/barrier.h>
#include <asm/local64.h>
#include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
#define MAX_L2_CTRS 9
@@ -87,8 +88,6 @@
#define L2_COUNTER_RELOAD BIT_ULL(31)
#define L2_CYCLE_COUNTER_RELOAD BIT_ULL(63)
-#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
-#define L2CPUSRDR_EL1 sys_reg(3, 3, 15, 0, 7)
#define reg_idx(reg, i) (((i) * IA_L2_REG_OFFSET) + reg##_BASE)
@@ -107,48 +106,7 @@
#define L2_EVENT_STREX 0x421
#define L2_EVENT_CLREX 0x422
-static DEFINE_RAW_SPINLOCK(l2_access_lock);
-/**
- * set_l2_indirect_reg: write value to an L2 register
- * @reg: Address of L2 register.
- * @value: Value to be written to register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static void set_l2_indirect_reg(u64 reg, u64 val)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2_access_lock, flags);
- write_sysreg_s(reg, L2CPUSRSELR_EL1);
- isb();
- write_sysreg_s(val, L2CPUSRDR_EL1);
- isb();
- raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-}
-
-/**
- * get_l2_indirect_reg: read an L2 register value
- * @reg: Address of L2 register.
- *
- * Use architecturally required barriers for ordering between system register
- * accesses
- */
-static u64 get_l2_indirect_reg(u64 reg)
-{
- u64 val;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2_access_lock, flags);
- write_sysreg_s(reg, L2CPUSRSELR_EL1);
- isb();
- val = read_sysreg_s(L2CPUSRDR_EL1);
- raw_spin_unlock_irqrestore(&l2_access_lock, flags);
-
- return val;
-}
struct cluster_pmu;
@@ -219,28 +177,28 @@ static inline struct cluster_pmu *get_cluster_pmu(
static void cluster_pmu_reset(void)
{
/* Reset all counters */
- set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
- set_l2_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
- set_l2_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
- set_l2_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
+ kryo_l2_set_indirect_reg(L2PMCNTENCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMINTENCLR, l2_counter_present_mask);
+ kryo_l2_set_indirect_reg(L2PMOVSCLR, l2_counter_present_mask);
}
static inline void cluster_pmu_enable(void)
{
- set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_ENABLE);
}
static inline void cluster_pmu_disable(void)
{
- set_l2_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
+ kryo_l2_set_indirect_reg(L2PMCR, L2PMCR_COUNTERS_DISABLE);
}
static inline void cluster_pmu_counter_set_value(u32 idx, u64 value)
{
if (idx == l2_cycle_ctr_idx)
- set_l2_indirect_reg(L2PMCCNTR, value);
+ kryo_l2_set_indirect_reg(L2PMCCNTR, value);
else
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx), value);
}
static inline u64 cluster_pmu_counter_get_value(u32 idx)
@@ -248,46 +206,46 @@ static inline u64 cluster_pmu_counter_get_value(u32 idx)
u64 value;
if (idx == l2_cycle_ctr_idx)
- value = get_l2_indirect_reg(L2PMCCNTR);
+ value = kryo_l2_get_indirect_reg(L2PMCCNTR);
else
- value = get_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
+ value = kryo_l2_get_indirect_reg(reg_idx(IA_L2PMXEVCNTR, idx));
return value;
}
static inline void cluster_pmu_counter_enable(u32 idx)
{
- set_l2_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMCNTENSET, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_disable(u32 idx)
{
- set_l2_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMCNTENCLR, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_enable_interrupt(u32 idx)
{
- set_l2_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMINTENSET, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_counter_disable_interrupt(u32 idx)
{
- set_l2_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
+ kryo_l2_set_indirect_reg(L2PMINTENCLR, idx_to_reg_bit(idx));
}
static inline void cluster_pmu_set_evccntcr(u32 val)
{
- set_l2_indirect_reg(L2PMCCNTCR, val);
+ kryo_l2_set_indirect_reg(L2PMCCNTCR, val);
}
static inline void cluster_pmu_set_evcntcr(u32 ctr, u32 val)
{
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVCNTCR, ctr), val);
}
static inline void cluster_pmu_set_evtyper(u32 ctr, u32 val)
{
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVTYPER, ctr), val);
}
static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
@@ -303,11 +261,11 @@ static void cluster_pmu_set_resr(struct cluster_pmu *cluster,
spin_lock_irqsave(&cluster->pmu_lock, flags);
- resr_val = get_l2_indirect_reg(L2PMRESR);
+ resr_val = kryo_l2_get_indirect_reg(L2PMRESR);
resr_val &= ~(L2PMRESR_GROUP_MASK << shift);
resr_val |= field;
resr_val |= L2PMRESR_EN;
- set_l2_indirect_reg(L2PMRESR, resr_val);
+ kryo_l2_set_indirect_reg(L2PMRESR, resr_val);
spin_unlock_irqrestore(&cluster->pmu_lock, flags);
}
@@ -323,14 +281,14 @@ static inline void cluster_pmu_set_evfilter_sys_mode(u32 ctr)
L2PMXEVFILTER_ORGFILTER_IDINDEP |
L2PMXEVFILTER_ORGFILTER_ALL;
- set_l2_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
+ kryo_l2_set_indirect_reg(reg_idx(IA_L2PMXEVFILTER, ctr), val);
}
static inline u32 cluster_pmu_getreset_ovsr(void)
{
- u32 result = get_l2_indirect_reg(L2PMOVSSET);
+ u32 result = kryo_l2_get_indirect_reg(L2PMOVSSET);
- set_l2_indirect_reg(L2PMOVSCLR, result);
+ kryo_l2_set_indirect_reg(L2PMOVSCLR, result);
return result;
}
@@ -783,7 +741,7 @@ static int get_num_counters(void)
{
int val;
- val = get_l2_indirect_reg(L2PMCR);
+ val = kryo_l2_get_indirect_reg(L2PMCR);
/*
* Read number of counters from L2PMCR and add 1
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 7093fe7..0567dff 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -39,6 +39,9 @@ config QCOM_GSBI
functions for connecting the underlying serial UART, SPI, and I2C
devices to the output pins.
+config QCOM_KRYO_L2_ACCESSORS
+ bool
+
config QCOM_MDT_LOADER
tristate
select QCOM_SCM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index cbf414c..e4d3f5a 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
obj-$(CONFIG_QCOM_SMSM) += smsm.o
obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
+obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) += kryo-l2-accessors.o
diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c
new file mode 100644
index 0000000..75fd07a
--- /dev/null
+++ b/drivers/soc/qcom/kryo-l2-accessors.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/spinlock.h>
+#include <asm/sysreg.h>
+#include <soc/qcom/kryo-l2-accessors.h>
+
+#define L2CPUSRSELR_EL1 sys_reg(3, 3, 15, 0, 6)
+#define L2CPUSRDR_EL1 sys_reg(3, 3, 15, 0, 7)
+
+static DEFINE_RAW_SPINLOCK(l2_access_lock);
+
+/**
+ * kryo_l2_set_indirect_reg() - write value to an L2 register
+ * @reg: Address of L2 register.
+ * @value: Value to be written to register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+void kryo_l2_set_indirect_reg(u64 reg, u64 val)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2_access_lock, flags);
+ write_sysreg_s(reg, L2CPUSRSELR_EL1);
+ isb();
+ write_sysreg_s(val, L2CPUSRDR_EL1);
+ isb();
+ raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+}
+EXPORT_SYMBOL(kryo_l2_set_indirect_reg);
+
+/**
+ * kryo_l2_get_indirect_reg() - read an L2 register value
+ * @reg: Address of L2 register.
+ *
+ * Use architecturally required barriers for ordering between system register
+ * accesses, and system registers with respect to device memory
+ */
+u64 kryo_l2_get_indirect_reg(u64 reg)
+{
+ u64 val;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2_access_lock, flags);
+ write_sysreg_s(reg, L2CPUSRSELR_EL1);
+ isb();
+ val = read_sysreg_s(L2CPUSRDR_EL1);
+ raw_spin_unlock_irqrestore(&l2_access_lock, flags);
+
+ return val;
+}
+EXPORT_SYMBOL(kryo_l2_get_indirect_reg);
diff --git a/include/soc/qcom/kryo-l2-accessors.h b/include/soc/qcom/kryo-l2-accessors.h
new file mode 100644
index 0000000..673c534
--- /dev/null
+++ b/include/soc/qcom/kryo-l2-accessors.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+#define __SOC_ARCH_QCOM_KRYO_L2_ACCESSORS_H
+
+void kryo_l2_set_indirect_reg(u64 reg, u64 val);
+u64 kryo_l2_get_indirect_reg(u64 reg);
+
+#endif
--
1.9.1
^ permalink raw reply related
* [PATCH v12 2/8] clk: qcom: Make clk_alpha_pll_configure available to modules
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
From: Rajendra Nayak <rnayak@codeaurora.org>
Allow clk_alpha_pll_configure to be called from loadable
kernel modules.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/clk-alpha-pll.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9722b70..57f2084 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -228,6 +228,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
if (pll->flags & SUPPORTS_FSM_MODE)
qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
}
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
{
--
1.9.1
^ permalink raw reply related
* [PATCH v12 3/8] clk: Use devm_ in the register fixed factor clock
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
Use devm_clk_hw_register instead of clk_hw_register
to simplify the usage of this API. This way drivers that call
the clk_hw_register_fixed_factor won't need to maintain
a data structure for further cleanup.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/clk-fixed-factor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index a5d402d..8e39bda 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -94,7 +94,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
init.num_parents = 1;
hw = &fix->hw;
- ret = clk_hw_register(dev, hw);
+ ret = devm_clk_hw_register(dev, hw);
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);
--
1.9.1
^ permalink raw reply related
* [PATCH v12 4/8] clk: qcom: Add CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below
+-------+
XO | |
+------------------>0 |
| |
PLL/2 | SMUX +----+
+------->1 | |
| | | |
| +-------+ | +-------+
| +---->0 |
| | |
+---------------+ | +----------->1 | CPU clk
|Primary PLL +----+ PLL_EARLY | | +------>
| +------+-----------+ +------>2 PMUX |
+---------------+ | | | |
| +------+ | +-->3 |
+--^+ ACD +-----+ | +-------+
+---------------+ +------+ |
|Alt PLL | |
| +---------------------------+
+---------------+ PLL_EARLY
The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.
The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.
So for frequencies above 600MHz we follow the following path
Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Support for this is added in a subsequent patch as well.
ACD stands for Adaptive Clock Distribution and is used to
detect voltage droops.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/Kconfig | 10 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/clk-alpha-pll.h | 6 +
drivers/clk/qcom/clk-cpu-8996.c | 403 +++++++++++++++++++++++++++++++++++++++
4 files changed, 420 insertions(+)
create mode 100644 drivers/clk/qcom/clk-cpu-8996.c
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index e42e1af..42e84b5 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -33,6 +33,16 @@ config QCOM_CLK_APCS_MSM8916
Say Y if you want to support CPU frequency scaling on devices
such as msm8916.
+config QCOM_CLK_APCC_MSM8996
+ tristate "MSM8996 CPU Clock Controller"
+ depends on ARM64
+ depends on COMMON_CLK_QCOM
+ select QCOM_KRYO_L2_ACCESSORS
+ help
+ Support for the CPU clock controller on msm8996 devices.
+ Say Y if you want to support CPU clock scaling using CPUfreq
+ drivers for dyanmic power management.
+
config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 7c09ab1..a822fc8 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
+obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index f981b48..9ce2a32 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -50,6 +50,12 @@ struct pll_vco {
u32 val;
};
+#define VCO(a, b, c) { \
+ .val = a,\
+ .min_freq = b,\
+ .max_freq = c,\
+}
+
/**
* struct clk_alpha_pll - phase locked loop (PLL)
* @offset: base address of registers
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
new file mode 100644
index 0000000..d92cad93
--- /dev/null
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+/*
+ * Each of the CPU clusters (Power and Perf) on msm8996 are
+ * clocked via 2 PLLs, a primary and alternate. There are also
+ * 2 Mux'es, a primary and secondary all connected together
+ * as shown below
+ *
+ * +-------+
+ * XO | |
+ * +------------------>0 |
+ * | |
+ * PLL/2 | SMUX +----+
+ * +------->1 | |
+ * | | | |
+ * | +-------+ | +-------+
+ * | +---->0 |
+ * | | |
+ * +---------------+ | +----------->1 | CPU clk
+ * |Primary PLL +----+ PLL_EARLY | | +------>
+ * | +------+-----------+ +------>2 PMUX |
+ * +---------------+ | | | |
+ * | +------+ | +-->3 |
+ * +--^+ ACD +-----+ | +-------+
+ * +---------------+ +------+ |
+ * |Alt PLL | |
+ * | +---------------------------+
+ * +---------------+ PLL_EARLY
+ *
+ * The primary PLL is what drives the CPU clk, except for times
+ * when we are reprogramming the PLL itself (for rate changes) when
+ * we temporarily switch to an alternate PLL. A subsequent patch adds
+ * support to switch between primary and alternate PLL during rate
+ * changes.
+ *
+ * The primary PLL operates on a single VCO range, between 600MHz
+ * and 3GHz. However the CPUs do support OPPs with frequencies
+ * between 300MHz and 600MHz. In order to support running the CPUs
+ * at those frequencies we end up having to lock the PLL at twice
+ * the rate and drive the CPU clk via the PLL/2 output and SMUX.
+ *
+ * So for frequencies above 600MHz we follow the following path
+ * Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
+ * and for frequencies between 300MHz and 600MHz we follow
+ * Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
+ * Support for this is added in a subsequent patch as well.
+ *
+ * ACD stands for Adaptive Clock Distribution and is used to
+ * detect voltage droops.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-regmap.h"
+
+enum _pmux_input {
+ DIV_2_INDEX = 0,
+ PLL_INDEX,
+ ACD_INDEX,
+ ALT_INDEX,
+ NUM_OF_PMUX_INPUTS
+};
+
+static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
+ [PLL_OFF_L_VAL] = 0x04,
+ [PLL_OFF_ALPHA_VAL] = 0x08,
+ [PLL_OFF_USER_CTL] = 0x10,
+ [PLL_OFF_CONFIG_CTL] = 0x18,
+ [PLL_OFF_CONFIG_CTL_U] = 0x1c,
+ [PLL_OFF_TEST_CTL] = 0x20,
+ [PLL_OFF_TEST_CTL_U] = 0x24,
+ [PLL_OFF_STATUS] = 0x28,
+};
+
+static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
+ [PLL_OFF_L_VAL] = 0x04,
+ [PLL_OFF_ALPHA_VAL] = 0x08,
+ [PLL_OFF_ALPHA_VAL_U] = 0x0c,
+ [PLL_OFF_USER_CTL] = 0x10,
+ [PLL_OFF_USER_CTL_U] = 0x14,
+ [PLL_OFF_CONFIG_CTL] = 0x18,
+ [PLL_OFF_TEST_CTL] = 0x20,
+ [PLL_OFF_TEST_CTL_U] = 0x24,
+ [PLL_OFF_STATUS] = 0x28,
+};
+
+/* PLLs */
+
+static const struct alpha_pll_config hfpll_config = {
+ .l = 60,
+ .config_ctl_val = 0x200d4828,
+ .config_ctl_hi_val = 0x006,
+ .pre_div_mask = BIT(12),
+ .post_div_mask = 0x3 << 8,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_pll = {
+ .offset = 0x80000,
+ .regs = prim_pll_regs,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "perfcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_pll = {
+ .offset = 0x0,
+ .regs = prim_pll_regs,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pwrcl_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+};
+
+static const struct pll_vco alt_pll_vco_modes[] = {
+ VCO(3, 250000000, 500000000),
+ VCO(2, 500000000, 750000000),
+ VCO(1, 750000000, 1000000000),
+ VCO(0, 1000000000, 2150400000),
+};
+
+static const struct alpha_pll_config altpll_config = {
+ .l = 16,
+ .vco_val = 0x3 << 20,
+ .vco_mask = 0x3 << 20,
+ .config_ctl_val = 0x4001051b,
+ .post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
+static struct clk_alpha_pll perfcl_alt_pll = {
+ .offset = 0x80100,
+ .regs = alt_pll_regs,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+static struct clk_alpha_pll pwrcl_alt_pll = {
+ .offset = 0x100,
+ .regs = alt_pll_regs,
+ .vco_table = alt_pll_vco_modes,
+ .num_vco = ARRAY_SIZE(alt_pll_vco_modes),
+ .flags = SUPPORTS_OFFLINE_REQ | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_alt_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_hwfsm_ops,
+ },
+};
+
+/* Mux'es */
+
+struct clk_cpu_8996_mux {
+ u32 reg;
+ u8 shift;
+ u8 width;
+ struct clk_hw *pll;
+ struct clk_regmap clkr;
+};
+
+static inline
+struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
+{
+ return container_of(to_clk_regmap(hw), struct clk_cpu_8996_mux, clkr);
+}
+
+static u8 clk_cpu_8996_mux_get_parent(struct clk_hw *hw)
+{
+ u32 val;
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ u32 mask = (u32)GENMASK(cpuclk->width - 1, 0);
+
+ regmap_read(clkr->regmap, cpuclk->reg, &val);
+ val >>= (u32)(cpuclk->shift);
+
+ return (u8)(val & mask);
+}
+
+static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ u32 val;
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ unsigned int mask = GENMASK(cpuclk->width + cpuclk->shift - 1,
+ cpuclk->shift);
+
+ val = (u32)index;
+ val <<= (u32)(cpuclk->shift);
+
+ return regmap_update_bits(clkr->regmap, cpuclk->reg, mask, val);
+}
+
+static int
+clk_cpu_8996_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
+ struct clk_hw *parent = cpuclk->pll;
+
+ req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
+ req->best_parent_hw = parent;
+
+ return 0;
+}
+
+const struct clk_ops clk_cpu_8996_mux_ops = {
+ .set_parent = clk_cpu_8996_mux_set_parent,
+ .get_parent = clk_cpu_8996_mux_get_parent,
+ .determine_rate = clk_cpu_8996_mux_determine_rate,
+};
+
+static struct clk_cpu_8996_mux pwrcl_smux = {
+ .reg = 0x40,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "pwrcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_smux = {
+ .reg = 0x80040,
+ .shift = 2,
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_smux",
+ .parent_names = (const char *[]){
+ "xo",
+ "perfcl_pll_main",
+ },
+ .num_parents = 2,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_cpu_8996_mux pwrcl_pmux = {
+ .reg = 0x40,
+ .shift = 0,
+ .width = 2,
+ .pll = &pwrcl_pll.clkr.hw,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "pwrcl_pmux",
+ .parent_names = (const char *[]){
+ "pwrcl_smux",
+ "pwrcl_pll",
+ "pwrcl_pll_acd",
+ "pwrcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ },
+};
+
+static struct clk_cpu_8996_mux perfcl_pmux = {
+ .reg = 0x80040,
+ .shift = 0,
+ .width = 2,
+ .pll = &perfcl_pll.clkr.hw,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "perfcl_pmux",
+ .parent_names = (const char *[]){
+ "perfcl_smux",
+ "perfcl_pll",
+ "perfcl_pll_acd",
+ "perfcl_alt_pll",
+ },
+ .num_parents = 4,
+ .ops = &clk_cpu_8996_mux_ops,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ },
+};
+
+static const struct regmap_config cpu_msm8996_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x80210,
+ .fast_io = true,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+struct clk_regmap *clks[] = {
+ &perfcl_pll.clkr,
+ &pwrcl_pll.clkr,
+ &perfcl_alt_pll.clkr,
+ &pwrcl_alt_pll.clkr,
+ &perfcl_smux.clkr,
+ &pwrcl_smux.clkr,
+ &perfcl_pmux.clkr,
+ &pwrcl_pmux.clkr,
+};
+
+static int
+qcom_cpu_clk_msm8996_register_clks(struct device *dev, struct regmap *regmap)
+{
+ int i, ret;
+
+ perfcl_smux.pll = clk_hw_register_fixed_factor(dev, "perfcl_pll_main",
+ "perfcl_pll",
+ CLK_SET_RATE_PARENT, 1, 2);
+
+ pwrcl_smux.pll = clk_hw_register_fixed_factor(dev, "pwrcl_pll_main",
+ "pwrcl_pll",
+ CLK_SET_RATE_PARENT, 1, 2);
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ ret = devm_clk_register_regmap(dev, clks[i]);
+ if (ret)
+ return ret;
+ }
+
+ clk_alpha_pll_configure(&perfcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&pwrcl_pll, regmap, &hfpll_config);
+ clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
+ clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+
+ return ret;
+}
+
+static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
+{
+ int ret;
+ void __iomem *base;
+ struct resource *res;
+ struct regmap *regmap;
+ struct clk_hw_onecell_data *data;
+ struct device *dev = &pdev->dev;
+
+ data = devm_kzalloc(dev, sizeof(*data) + 2 * sizeof(struct clk_hw *),
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ regmap = devm_regmap_init_mmio(dev, base, &cpu_msm8996_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ret = qcom_cpu_clk_msm8996_register_clks(dev, regmap);
+ if (ret)
+ return ret;
+
+ data->hws[0] = &pwrcl_pmux.clkr.hw;
+ data->hws[1] = &perfcl_pmux.clkr.hw;
+ data->num = 2;
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
+}
+
+static const struct of_device_id qcom_cpu_clk_msm8996_match_table[] = {
+ { .compatible = "qcom,msm8996-apcc" },
+ {}
+};
+
+static struct platform_driver qcom_cpu_clk_msm8996_driver = {
+ .probe = qcom_cpu_clk_msm8996_driver_probe,
+ .driver = {
+ .name = "qcom-msm8996-apcc",
+ .of_match_table = qcom_cpu_clk_msm8996_match_table,
+ },
+};
+module_platform_driver(qcom_cpu_clk_msm8996_driver);
+
+MODULE_ALIAS("platform:msm8996-apcc");
+MODULE_DESCRIPTION("QCOM MSM8996 CPU Clock Driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* [PATCH v12 5/8] dt-bindings: clk: qcom: Add bindings for CPU clock for msm8996
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
Each of the CPU clusters (Power and Perf) on msm8996 are
clocked via 2 PLLs, a primary and alternate. There are also
2 Mux'es, a primary and secondary all connected together
as shown below
+-------+
XO | |
+------------------>0 |
| |
PLL/2 | SMUX +----+
+------->1 | |
| | | |
| +-------+ | +-------+
| +---->0 |
| | |
+---------------+ | +----------->1 | CPU clk
|Primary PLL +----+ PLL_EARLY | | +------>
| +------+-----------+ +------>2 PMUX |
+---------------+ | | | |
| +------+ | +-->3 |
+--^+ ACD +-----+ | +-------+
+---------------+ +------+ |
|Alt PLL | |
| +---------------------------+
+---------------+ PLL_EARLY
The primary PLL is what drives the CPU clk, except for times
when we are reprogramming the PLL itself (for rate changes) when
we temporarily switch to an alternate PLL. A subsequent patch adds
support to switch between primary and alternate PLL during rate
changes.
The primary PLL operates on a single VCO range, between 600MHz
and 3GHz. However the CPUs do support OPPs with frequencies
between 300MHz and 600MHz. In order to support running the CPUs
at those frequencies we end up having to lock the PLL at twice
the rate and drive the CPU clk via the PLL/2 output and SMUX.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/clock/qcom,kryocc.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,kryocc.txt
diff --git a/Documentation/devicetree/bindings/clock/qcom,kryocc.txt b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
new file mode 100644
index 0000000..8458783
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,kryocc.txt
@@ -0,0 +1,17 @@
+Qualcomm CPUSS clock controller for Kryo CPUs
+----------------------------------------------------
+
+Required properties :
+- compatible : shall contain only one of the following:
+
+ "qcom,msm8996-apcc"
+
+- reg : shall contain base register location and length
+- #clock-cells : shall contain 1
+
+Example:
+ kryocc: clock-controller at 6400000 {
+ compatible = "qcom,msm8996-apcc";
+ reg = <0x6400000 0x90000>;
+ #clock-cells = <1>;
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v12 6/8] clk: qcom: cpu-8996: Add support to switch to alternate PLL
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
From: Rajendra Nayak <rnayak@codeaurora.org>
Each of the CPU clusters on msm8996 are powered via a primary
PLL and a secondary PLL. The primary PLL is what drives the
CPU clk, except for times when we are reprogramming the PLL
itself, when we temporarily switch to an alternate PLL.
Use clock rate change notifiers to support this.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/clk-cpu-8996.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index d92cad93..620fdc2 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -52,6 +52,7 @@
* detect voltage droops.
*/
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -178,10 +179,14 @@ struct clk_cpu_8996_mux {
u32 reg;
u8 shift;
u8 width;
+ struct notifier_block nb;
struct clk_hw *pll;
struct clk_regmap clkr;
};
+#define to_clk_cpu_8996_mux_nb(_nb) \
+ container_of(_nb, struct clk_cpu_8996_mux, nb)
+
static inline
struct clk_cpu_8996_mux *to_clk_cpu_8996_mux_hw(struct clk_hw *hw)
{
@@ -227,6 +232,26 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
return 0;
}
+int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ int ret;
+ struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+ break;
+ case POST_RATE_CHANGE:
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return notifier_from_errno(ret);
+};
const struct clk_ops clk_cpu_8996_mux_ops = {
.set_parent = clk_cpu_8996_mux_set_parent,
.get_parent = clk_cpu_8996_mux_get_parent,
@@ -270,6 +295,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
.parent_names = (const char *[]){
@@ -289,6 +315,7 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
+ .nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
.parent_names = (const char *[]){
@@ -347,6 +374,12 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+ ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
+ if (ret)
+ return ret;
+
+ ret = clk_notifier_register(perfcl_pmux.clkr.hw.clk, &perfcl_pmux.nb);
+
return ret;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v12 7/8] clk: qcom: cpu-8996: Add support to switch below 600Mhz
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
The CPU clock controller's primary PLL operates on a single VCO range,
between 600MHz and 3GHz. However the CPUs do support OPPs with
frequencies between 300MHz and 600MHz. In order to support running the
CPUs at those frequencies we end up having to lock the PLL at twice the
rate and drive the CPU clk via the PLL/2 output and SMUX.
So for frequencies above 600MHz we follow the following path
Primary PLL --> PLL_EARLY --> PMUX(1) --> CPU clk
and for frequencies between 300MHz and 600MHz we follow
Primary PLL --> PLL/2 --> SMUX(1) --> PMUX(0) --> CPU clk
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/clk-cpu-8996.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 620fdc2..ff5c0a5 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -68,6 +68,8 @@ enum _pmux_input {
NUM_OF_PMUX_INPUTS
};
+#define DIV_2_THRESHOLD 600000000
+
static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
[PLL_OFF_ALPHA_VAL] = 0x08,
@@ -95,10 +97,11 @@ enum _pmux_input {
static const struct alpha_pll_config hfpll_config = {
.l = 60,
- .config_ctl_val = 0x200d4828,
+ .config_ctl_val = 0x200d4aa8,
.config_ctl_hi_val = 0x006,
.pre_div_mask = BIT(12),
.post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
};
@@ -140,7 +143,7 @@ enum _pmux_input {
.vco_mask = 0x3 << 20,
.config_ctl_val = 0x4001051b,
.post_div_mask = 0x3 << 8,
- .post_div_val = 0x1,
+ .post_div_val = 0x1 << 8,
.main_output_mask = BIT(0),
.early_output_mask = BIT(3),
};
@@ -181,6 +184,7 @@ struct clk_cpu_8996_mux {
u8 width;
struct notifier_block nb;
struct clk_hw *pll;
+ struct clk_hw *pll_div_2;
struct clk_regmap clkr;
};
@@ -226,6 +230,13 @@ static int clk_cpu_8996_mux_set_parent(struct clk_hw *hw, u8 index)
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_hw(hw);
struct clk_hw *parent = cpuclk->pll;
+ if (cpuclk->pll_div_2 && req->rate < DIV_2_THRESHOLD) {
+ if (req->rate < (DIV_2_THRESHOLD / 2))
+ return -EINVAL;
+
+ parent = cpuclk->pll_div_2;
+ }
+
req->best_parent_rate = clk_hw_round_rate(parent, req->rate);
req->best_parent_hw = parent;
@@ -237,13 +248,19 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
{
int ret;
struct clk_cpu_8996_mux *cpuclk = to_clk_cpu_8996_mux_nb(nb);
+ struct clk_notifier_data *cnd = data;
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
break;
case POST_RATE_CHANGE:
- ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, PLL_INDEX);
+ if (cnd->new_rate < DIV_2_THRESHOLD)
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ DIV_2_INDEX);
+ else
+ ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
+ PLL_INDEX);
break;
default:
ret = 0;
@@ -295,6 +312,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
+ .pll_div_2 = &pwrcl_smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "pwrcl_pmux",
@@ -315,6 +333,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
+ .pll_div_2 = &perfcl_smux.clkr.hw,
.nb.notifier_call = cpu_clk_notifier_cb,
.clkr.hw.init = &(struct clk_init_data) {
.name = "perfcl_pmux",
--
1.9.1
^ permalink raw reply related
* [PATCH v12 8/8] clk: qcom: Add ACD path to CPU clock driver for msm8996
From: Ilia Lin @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527148218-16540-1-git-send-email-ilialin@codeaurora.org>
The PMUX for each duplex allows for selection of ACD clock source.
The DVM (Dynamic Variation Monitor) will flag an error
when a voltage droop event is detected. This flagged error
enables ACD to provide a div-by-2 clock, sourced from the primary PLL.
The duplex will be provided the divided clock
until a pre-programmed delay has expired.
This change configures ACD during the probe and switches
the PMUXes to the ACD clock source.
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
---
drivers/clk/qcom/clk-cpu-8996.c | 75 +++++++++++++++++++++++++++++++++++------
1 file changed, 65 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index ff5c0a5..0a908d8 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -53,9 +53,11 @@
*/
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <soc/qcom/kryo-l2-accessors.h>
#include "clk-alpha-pll.h"
#include "clk-regmap.h"
@@ -69,6 +71,11 @@ enum _pmux_input {
};
#define DIV_2_THRESHOLD 600000000
+#define PWRCL_REG_OFFSET 0x0
+#define PERFCL_REG_OFFSET 0x80000
+#define MUX_OFFSET 0x40
+#define ALT_PLL_OFFSET 0x100
+#define SSSCTL_OFFSET 0x160
static const u8 prim_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_L_VAL] = 0x04,
@@ -107,7 +114,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll perfcl_pll = {
- .offset = 0x80000,
+ .offset = PERFCL_REG_OFFSET,
.regs = prim_pll_regs,
.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
.clkr.hw.init = &(struct clk_init_data){
@@ -119,7 +126,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll pwrcl_pll = {
- .offset = 0x0,
+ .offset = PWRCL_REG_OFFSET,
.regs = prim_pll_regs,
.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
.clkr.hw.init = &(struct clk_init_data){
@@ -149,7 +156,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll perfcl_alt_pll = {
- .offset = 0x80100,
+ .offset = PERFCL_REG_OFFSET + ALT_PLL_OFFSET,
.regs = alt_pll_regs,
.vco_table = alt_pll_vco_modes,
.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
@@ -163,7 +170,7 @@ enum _pmux_input {
};
static struct clk_alpha_pll pwrcl_alt_pll = {
- .offset = 0x100,
+ .offset = PWRCL_REG_OFFSET + ALT_PLL_OFFSET,
.regs = alt_pll_regs,
.vco_table = alt_pll_vco_modes,
.num_vco = ARRAY_SIZE(alt_pll_vco_modes),
@@ -176,6 +183,9 @@ enum _pmux_input {
},
};
+void __iomem *base;
+static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base);
+
/* Mux'es */
struct clk_cpu_8996_mux {
@@ -253,6 +263,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
switch (event) {
case PRE_RATE_CHANGE:
ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
+ qcom_cpu_clk_msm8996_acd_init(base);
break;
case POST_RATE_CHANGE:
if (cnd->new_rate < DIV_2_THRESHOLD)
@@ -260,7 +271,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
DIV_2_INDEX);
else
ret = clk_cpu_8996_mux_set_parent(&cpuclk->clkr.hw,
- PLL_INDEX);
+ ACD_INDEX);
break;
default:
ret = 0;
@@ -276,7 +287,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux pwrcl_smux = {
- .reg = 0x40,
+ .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
.shift = 2,
.width = 2,
.clkr.hw.init = &(struct clk_init_data) {
@@ -292,7 +303,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux perfcl_smux = {
- .reg = 0x80040,
+ .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
.shift = 2,
.width = 2,
.clkr.hw.init = &(struct clk_init_data) {
@@ -308,7 +319,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux pwrcl_pmux = {
- .reg = 0x40,
+ .reg = PWRCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = &pwrcl_pll.clkr.hw,
@@ -329,7 +340,7 @@ int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
};
static struct clk_cpu_8996_mux perfcl_pmux = {
- .reg = 0x80040,
+ .reg = PERFCL_REG_OFFSET + MUX_OFFSET,
.shift = 0,
.width = 2,
.pll = &perfcl_pll.clkr.hw,
@@ -393,6 +404,10 @@ struct clk_regmap *clks[] = {
clk_alpha_pll_configure(&perfcl_alt_pll, regmap, &altpll_config);
clk_alpha_pll_configure(&pwrcl_alt_pll, regmap, &altpll_config);
+ /* Enable alt PLLs */
+ clk_prepare_enable(pwrcl_alt_pll.clkr.hw.clk);
+ clk_prepare_enable(perfcl_alt_pll.clkr.hw.clk);
+
ret = clk_notifier_register(pwrcl_pmux.clkr.hw.clk, &pwrcl_pmux.nb);
if (ret)
return ret;
@@ -402,10 +417,48 @@ struct clk_regmap *clks[] = {
return ret;
}
+#define CPU_AFINITY_MASK 0xFFF
+#define PWRCL_CPU_REG_MASK 0x3
+#define PERFCL_CPU_REG_MASK 0x103
+
+#define L2ACDCR_REG 0x580ULL
+#define L2ACDTD_REG 0x581ULL
+#define L2ACDDVMRC_REG 0x584ULL
+#define L2ACDSSCR_REG 0x589ULL
+
+static DEFINE_SPINLOCK(acd_lock);
+
+static void qcom_cpu_clk_msm8996_acd_init(void __iomem *base)
+{
+ u64 hwid;
+ unsigned long flags;
+
+ spin_lock_irqsave(&acd_lock, flags);
+
+ hwid = read_cpuid_mpidr() & CPU_AFINITY_MASK;
+
+ kryo_l2_set_indirect_reg(L2ACDTD_REG, 0x00006A11);
+ kryo_l2_set_indirect_reg(L2ACDDVMRC_REG, 0x000E0F0F);
+ kryo_l2_set_indirect_reg(L2ACDSSCR_REG, 0x00000601);
+
+ if (PWRCL_CPU_REG_MASK == (hwid | PWRCL_CPU_REG_MASK)) {
+ writel(0xF, base + PWRCL_REG_OFFSET + SSSCTL_OFFSET);
+ wmb();
+ kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002C5FFD);
+ }
+
+ if (PERFCL_CPU_REG_MASK == (hwid | PERFCL_CPU_REG_MASK)) {
+ kryo_l2_set_indirect_reg(L2ACDCR_REG, 0x002C5FFD);
+ writel(0xF, base + PERFCL_REG_OFFSET + SSSCTL_OFFSET);
+ wmb();
+ }
+
+ spin_unlock_irqrestore(&acd_lock, flags);
+}
+
static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
{
int ret;
- void __iomem *base;
struct resource *res;
struct regmap *regmap;
struct clk_hw_onecell_data *data;
@@ -429,6 +482,8 @@ static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
if (ret)
return ret;
+ qcom_cpu_clk_msm8996_acd_init(base);
+
data->hws[0] = &pwrcl_pmux.clkr.hw;
data->hws[1] = &perfcl_pmux.clkr.hw;
data->num = 2;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 2/4] drm/mediatek: Add support for mediatek SOC MT2712
From: Stu Hsieh @ 2018-05-24 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527125197.6406.10.camel@mtksdaap41>
Hi CK,
On Thu, 2018-05-24 at 09:26 +0800, CK Hu wrote:
> Hi, Stu:
>
> On Wed, 2018-05-23 at 17:28 +0800, Stu Hsieh wrote:
> > On Wed, 2018-05-23 at 13:23 +0800, CK Hu wrote:
> > > Hi, Stu:
> > >
> > > I've some inline comment.
> > >
> > > On Wed, 2018-05-23 at 10:25 +0800, Stu Hsieh wrote:
> > > > This patch add support for the Mediatek MT2712 DISP subsystem.
> > > > There are two OVL engine and three disp output in MT2712.
> > > >
> > > > Signed-off-by: Stu Hsieh <stu.hsieh@mediatek.com>
> > > > ---
> > > > drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 50 +++++++++++++++++++++++++++--
> > > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 8 +++--
> > > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 7 ++--
> > > > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 47 +++++++++++++++++++++++++--
> > > > drivers/gpu/drm/mediatek/mtk_drm_drv.h | 7 ++--
> > > > 5 files changed, 108 insertions(+), 11 deletions(-)
> > > >
> > > > +#define MT2712_MUTEX_MOD_DISP_AAL0 BIT(20)
> > > > +#define MT2712_MUTEX_MOD_DISP_UFOE BIT(22)
> > > > +#define MT2712_MUTEX_MOD_DISP_PWM0 BIT(23)
> > > > +#define MT2712_MUTEX_MOD_DISP_PWM1 BIT(24)
> > > > +#define MT2712_MUTEX_MOD_DISP_PWM2 BIT(10)
> > > > +#define MT2712_MUTEX_MOD_DISP_OD0 BIT(25)
> > > > +/* modules more than 32, add BIT(31) when using DISP_REG_MUTEX_MOD2 bit */
> > > > +#define MT2712_MUTEX_MOD2_DISP_AAL1 (BIT(1) | BIT(31))
> > >
> > > I think a better definition is
> > >
> > > #define MT2712_MUTEX_MOD2_DISP_AAL1 BIT(33)
> > >
> > > when you need to access this register,
> > >
> > > if (ddp->mutex_mod[id] < BIT(32)) {
> > > offset = DISP_REG_MUTEX_MOD(mutex->id);
> > > reg = readl_relaxed(ddp->regs + offset);
> > > reg |= ddp->mutex_mod[id];
> > > writel_relaxed(reg, ddp->regs + offset);
> > > } else {
> > > offset = DISP_REG_MUTEX_MOD2(mutex->id);
> > > reg = readl_relaxed(ddp->regs + offset);
> > > reg |= (ddp->mutex_mod[id] >> 32);
> > > writel_relaxed(reg, ddp->regs + offset);
> > > }
> > >
> > > because DISP_REG_MUTEX_MOD BIT(31) could be used for some module.
> >
> > This modification is workable, but result some build warning like
> > following:
> > 1. #define BIT(nr) (1UL << (nr)) in include/linux/bitops.h
> > 2. [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
> > => we need to modify the definition about "static const unsigned int
> > mt2712_mutex_mod"
> >
>
> Currently, mutex_mod is a bitwise definition. I think it could be
> changed to index definition such as
>
>
> #define MT2712_MUTEX_MOD_DISP_PWM2 10
> #define MT2712_MUTEX_MOD_DISP_OD0 25
> #define MT2712_MUTEX_MOD2_DISP_AAL1 33
>
> when you need to access this register,
>
> if (ddp->mutex_mod[id] < 32) {
> offset = DISP_REG_MUTEX_MOD(mutex->id);
> reg = readl_relaxed(ddp->regs + offset);
> reg |= 1 << ddp->mutex_mod[id];
> writel_relaxed(reg, ddp->regs + offset);
> } else {
> offset = DISP_REG_MUTEX_MOD2(mutex->id);
> reg = readl_relaxed(ddp->regs + offset);
> reg |= 1 << (ddp->mutex_mod[id] - 32);
> writel_relaxed(reg, ddp->regs + offset);
> }
>
> Regards,
> CK
ok, these modification has no build warning.
I would also change the definition about 2701 and 8173 from bitwise to
index.
>
> > > > +#define MT2712_MUTEX_MOD2_DISP_OD1 (BIT(2) | BIT(31))
> > > > +
> > > > #define MT2701_MUTEX_MOD_DISP_OVL BIT(3)
> > > > #define MT2701_MUTEX_MOD_DISP_WDMA BIT(6)
> > > > #define MT2701_MUTEX_MOD_DISP_COLOR BIT(7)
> > > > @@ -74,6 +96,7 @@
> > > >
> > > >
> > >
> > >
> >
> >
>
>
^ permalink raw reply
* [PATCH 1/5] pinctrl: at91-pio4: add missing of_node_put
From: Ludovic Desroches @ 2018-05-24 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527102436-13447-2-git-send-email-Julia.Lawall@lip6.fr>
On Wed, May 23, 2018 at 09:07:12PM +0200, Julia Lawall wrote:
> The device node iterators perform an of_node_get on each iteration, so a
> jump out of the loop requires an of_node_put.
>
> The semantic patch that fixes this problem is as follows
> (http://coccinelle.lip6.fr):
>
> // <smpl>
> @@
> expression root,e;
> local idexpression child;
> iterator name for_each_child_of_node;
> @@
>
> for_each_child_of_node(root, child) {
> ... when != of_node_put(child)
> when != e = child
> + of_node_put(child);
> ? break;
> ...
> }
> ... when != child
> // </smpl>
>
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com>
Thanks
>
> ---
> drivers/pinctrl/pinctrl-at91-pio4.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
> index 4b57a13..bafb3d4 100644
> --- a/drivers/pinctrl/pinctrl-at91-pio4.c
> +++ b/drivers/pinctrl/pinctrl-at91-pio4.c
> @@ -576,8 +576,10 @@ static int atmel_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
> for_each_child_of_node(np_config, np) {
> ret = atmel_pctl_dt_subnode_to_map(pctldev, np, map,
> &reserved_maps, num_maps);
> - if (ret < 0)
> + if (ret < 0) {
> + of_node_put(np);
> break;
> + }
> }
> }
>
>
^ 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