* [PATCH v2 12/26] drm/sun4i: Add support for multiple DW HDMI PHY clock parents
From: Sergey Suloev @ 2018-05-18 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4909574.Q3IFWM0xt6@jernej-laptop>
Hi, guys,
On 05/18/2018 05:46 PM, Jernej ?krabec wrote:
> Hi,
>
> Dne petek, 18. maj 2018 ob 12:01:16 CEST je Maxime Ripard napisal(a):
>> On Fri, May 18, 2018 at 03:15:22PM +0530, Jagan Teki wrote:
>>> From: Jernej Skrabec <jernej.skrabec@siol.net>
>>>
>>> Some SoCs with DW HDMI have multiple possible clock parents, like A64
>>> and R40.
>>>
>>> Expand HDMI PHY clock driver to support second clock parent.
>>>
>>> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>>> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
>>> ---
>>> Changes for v2:
>>> - new patch
>>>
>>> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 9 ++-
>>> drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 33 ++++++++---
>>> drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 89
>>> ++++++++++++++++++++++-------- 3 files changed, 96 insertions(+), 35
>>> deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
>>> b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index 79154f0f674a..303189d6602c
>>> 100644
>>> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
>>> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
>>> @@ -98,7 +98,8 @@
>>>
>>> #define SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN BIT(29)
>>> #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN BIT(28)
>>> #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 BIT(27)
>>>
>>> -#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL BIT(26)
>>> +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK BIT(26)
>>> +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT 26
>>>
>>> #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN BIT(25)
>>> #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x) ((x) << 22)
>>> #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x) ((x) << 20)
>>>
>>> @@ -146,7 +147,7 @@
>>>
>>> struct sun8i_hdmi_phy;
>>>
>>> struct sun8i_hdmi_phy_variant {
>>>
>>> - bool has_phy_clk;
>>> + int phy_clk_num;
>>>
>>> void (*phy_init)(struct sun8i_hdmi_phy *phy);
>>> void (*phy_disable)(struct dw_hdmi *hdmi,
>>>
>>> struct sun8i_hdmi_phy *phy);
>>>
>>> @@ -160,6 +161,7 @@ struct sun8i_hdmi_phy {
>>>
>>> struct clk *clk_mod;
>>> struct clk *clk_phy;
>>> struct clk *clk_pll0;
>>>
>>> + struct clk *clk_pll1;
>>>
>>> unsigned int rcal;
>>> struct regmap *regs;
>>> struct reset_control *rst_phy;
>>>
>>> @@ -188,6 +190,7 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi
>>> *hdmi);
>>>
>>> void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
>>> const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
>>>
>>> -int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
>>> +int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
>>> + int clk_num);
>>>
>>> #endif /* _SUN8I_DW_HDMI_H_ */
>>>
>>> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
>>> b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 5a52fc489a9d..0eadf087fc46
>>> 100644
>>> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
>>> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
>>> @@ -183,7 +183,13 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi
>>> *hdmi,>
>>> regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
>>>
>>> SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK, 0);
>>>
>>> - regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, pll_cfg1_init);
>>> + /*
>>> + * NOTE: We have to be careful not to overwrite PHY parent
>>> + * clock selection bit and clock divider.
>>> + */
>>> + regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
>>> + (u32)~SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
>>> + pll_cfg1_init);
>>>
>>> regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
>>>
>>> (u32)~SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
>>> pll_cfg2_init);
>>>
>>> @@ -232,7 +238,7 @@ static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi,
>>> void *data,>
>>> regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
>>>
>>> SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK, val);
>>>
>>> - if (phy->variant->has_phy_clk)
>>> + if (phy->variant->phy_clk_num)
>>>
>>> clk_set_rate(phy->clk_phy, mode->crtc_clock * 1000);
>>>
>>> return phy->variant->phy_config(hdmi, phy, mode->crtc_clock * 1000);
>>>
>>> @@ -393,7 +399,7 @@ static const struct sun8i_hdmi_phy_variant
>>> sun8i_a83t_hdmi_phy = {>
>>> };
>>>
>>> static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
>>>
>>> - .has_phy_clk = true,
>>> + .phy_clk_num = 1,
>>>
>>> .phy_init = &sun8i_hdmi_phy_init_h3,
>>> .phy_disable = &sun8i_hdmi_phy_disable_h3,
>>> .phy_config = &sun8i_hdmi_phy_config_h3,
>>>
>>> @@ -464,7 +470,7 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi,
>>> struct device_node *node)>
>>> goto err_put_clk_bus;
>>>
>>> }
>>>
>>> - if (phy->variant->has_phy_clk) {
>>> + if (phy->variant->phy_clk_num) {
>>>
>>> phy->clk_pll0 = of_clk_get_by_name(node, "pll-0");
>>> if (IS_ERR(phy->clk_pll0)) {
>>>
>>> dev_err(dev, "Could not get pll-0 clock\n");
>>>
>>> @@ -472,7 +478,16 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi,
>>> struct device_node *node)>
>>> goto err_put_clk_mod;
>>>
>>> }
>>>
>>> - ret = sun8i_phy_clk_create(phy, dev);
>>> + if (phy->variant->phy_clk_num) {
>>> + phy->clk_pll1 = of_clk_get_by_name(node, "pll-1");
>>> + if (IS_ERR(phy->clk_pll1)) {
>>> + dev_err(dev, "Could not get pll-1 clock\n");
>>> + ret = PTR_ERR(phy->clk_pll1);
>>> + goto err_put_clk_mod;
>>> + }
>>> + }
>>> +
>> You have a bug here. If phy_clk_num == 1, you'll still try to lookup
>> pll-1.
> This is actually WIP patch taken from my github. This issue was fixed already
> locally on disk. I thought Jagan will not use it until SRAM C patches land.
>
>> And this is a bit sloppy, since if phy_clk_num == 3, you won't try to
>> lookup pll-2 either.
> It is highly unlikely this will be higher than 2, at least for this HDMI PHY,
> since it has only 1 bit reserved for parent selection. But since I have to fix
> it, I'll add ">= 2"
>
>>> + ret = sun8i_phy_clk_create(phy, dev, phy->variant->phy_clk_num);
>>>
>>> if (ret) {
>>>
>>> dev_err(dev, "Couldn't create the PHY clock\n");
>>> goto err_put_clk_pll0;
>>>
>>> @@ -515,8 +530,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi,
>>> struct device_node *node)>
>>> err_put_rst_phy:
>>> reset_control_put(phy->rst_phy);
>>>
>>> err_put_clk_pll0:
>>> - if (phy->variant->has_phy_clk)
>>> - clk_put(phy->clk_pll0);
>>> + clk_put(phy->clk_pll0);
>>> + clk_put(phy->clk_pll1);
>>>
>>> err_put_clk_mod:
>>> clk_put(phy->clk_mod);
>>>
>>> err_put_clk_bus:
>>> @@ -536,8 +551,8 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
>>>
>>> reset_control_put(phy->rst_phy);
>>>
>>> - if (phy->variant->has_phy_clk)
>>> - clk_put(phy->clk_pll0);
>>> + clk_put(phy->clk_pll0);
>>> + clk_put(phy->clk_pll1);
>>>
>>> clk_put(phy->clk_mod);
>>> clk_put(phy->clk_bus);
>>>
>>> }
>>>
>>> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
>>> b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c index
>>> faea449812f8..85b12fc96dbc 100644
>>> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
>>> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
>>> @@ -22,29 +22,36 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw
>>> *hw,>
>>> {
>>>
>>> unsigned long rate = req->rate;
>>> unsigned long best_rate = 0;
>>>
>>> - struct clk_hw *parent;
>>> + struct clk_hw *best_parent = NULL;
>>> + struct clk_hw *parent = NULL;
>>>
>>> int best_div = 1;
>>>
>>> - int i;
>>> + int i, p;
>>>
>>> - parent = clk_hw_get_parent(hw);
>>> -
>>> - for (i = 1; i <= 16; i++) {
>>> - unsigned long ideal = rate * i;
>>> - unsigned long rounded;
>>> -
>>> - rounded = clk_hw_round_rate(parent, ideal);
>>> -
>>> - if (rounded == ideal) {
>>> - best_rate = rounded;
>>> - best_div = i;
>>> - break;
>>> - }
>>> + for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
>>> + parent = clk_hw_get_parent_by_index(hw, p);
>>> + if (!parent)
>>> + continue;
>>>
>>> - if (!best_rate ||
>>> - abs(rate - rounded / i) <
>>> - abs(rate - best_rate / best_div)) {
>>> - best_rate = rounded;
>>> - best_div = i;
>>> + for (i = 1; i <= 16; i++) {
>>> + unsigned long ideal = rate * i;
>>> + unsigned long rounded;
>>> +
>>> + rounded = clk_hw_round_rate(parent, ideal);
>>> +
>>> + if (rounded == ideal) {
>>> + best_rate = rounded;
>>> + best_div = i;
>>> + best_parent = parent;
>>> + break;
>>> + }
>>> +
>>> + if (!best_rate ||
>>> + abs(rate - rounded / i) <
>>> + abs(rate - best_rate / best_div)) {
>>> + best_rate = rounded;
>>> + best_div = i;
>>> + best_parent = parent;
>>> + }
>>>
>>> }
>>>
>>> }
>>>
>>> @@ -95,22 +102,58 @@ static int sun8i_phy_clk_set_rate(struct clk_hw *hw,
>>> unsigned long rate,>
>>> return 0;
>>>
>>> }
>>>
>>> +static u8 sun8i_phy_clk_get_parent(struct clk_hw *hw)
>>> +{
>>> + struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
>>> + u32 reg;
>>> +
>>> + regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, ®);
>>> + reg = (reg & SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK) >>
>>> + SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT;
>>> +
>>> + return reg;
>>> +}
>>> +
>>> +static int sun8i_phy_clk_set_parent(struct clk_hw *hw, u8 index)
>>> +{
>>> + struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
>>> +
>>> + if (index > 1)
>>> + return -EINVAL;
>>> +
>>> + regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
>>> + SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
>>> + index << SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT);
>>> +
>>> + return 0;
>>> +}
>>> +
>> The DT bindings changes and the clk changes should be part of separate
>> patches.
> By DT bindings changes you mean code which reads DT and not DT documentation,
> right?
>
> Ok, I'll split it.
>
> BTW, I'll resend fixed version of this patch for my R40 HDMI series, since
> there is nothing to hold it back, unlike for this.
>
> Best regards,
> Jernej
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
you have been talking about SRAM patches, required for A64 DE2, for
about a half a year.
May I ask you to explain in a couple of words why they are so important ?
I am really curious because I have DE2 already working on my A64 without
those magic patches..
Thanks,
Sergey
^ permalink raw reply
* [PATCH 6/6] arm64: perf: Add support for chaining counters
From: Robin Murphy @ 2018-05-18 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526638943-2110-7-git-send-email-suzuki.poulose@arm.com>
One more thing now that I've actually looked at the Arm ARM...
On 18/05/18 11:22, Suzuki K Poulose wrote:
[...]
> +static inline void armv8pmu_write_event_type(struct perf_event *event)
> +{
> + struct hw_perf_event *hwc = &event->hw;
> + int idx = hwc->idx;
> +
> + /*
> + * For chained events, write the high counter event type
> + * followed by the low counter.
> + */
> + if (armv8pmu_event_is_chained(event)) {
> + u32 chain_evt = ARMV8_PMUV3_PERFCTR_CHAIN;
> +
> + /* Set the filters as that of the main event for chain */
> + chain_evt |= hwc->config_base & ~ARMV8_PMU_EVTYPE_EVENT;
The description of the chain event says that the filtering must only be
set on the lower counter, and that the chain event itself should be set
to count everything.
> + armv8pmu_write_evtype(idx, chain_evt);
> + isb();
> + idx--;
> + }
> +
> + armv8pmu_write_evtype(idx, hwc->config_base);
It also says that the 'real' event should be set up first and the chain
event second, with the rather ominous warning of "If software does not
program the event in this way, the count becomes UNPREDICTABLE."
Robin.
^ permalink raw reply
* [PATCH 14/17] dt-bindings/interrupt-controller: add description for Marvell SEI node
From: Miquel Raynal @ 2018-05-18 14:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAL_JsqJ51riH+9Any7Bc6DN0Dx+WJdDAvOQ1gJCXTTUW0EUWsQ@mail.gmail.com>
Hi Rob,
On Mon, 30 Apr 2018 09:09:10 -0500, Rob Herring <robh@kernel.org> wrote:
> On Sat, Apr 28, 2018 at 5:48 AM, Miquel Raynal
> <miquel.raynal@bootlin.com> wrote:
> > Hi Rob,
> >
> > On Fri, 27 Apr 2018 15:50:32 -0500, Rob Herring <robh@kernel.org> wrote:
> >
> >> On Sat, Apr 21, 2018 at 03:55:34PM +0200, Miquel Raynal wrote:
> >> > Describe the SEI (System Error Interrupt) controller driver. The
> >> > controller is part of the GIC. It aggregates two types of interrupts,
> >> > wired and MSIs from respectively the AP and the CPs, into a single SPI
> >> > interrupt.
> >> >
> >> > Suggested-by: Haim Boot <hayim@marvell.com>
> >> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> >> > ---
> >> > .../bindings/interrupt-controller/marvell,sei.txt | 54 ++++++++++++++++++++++
> >> > 1 file changed, 54 insertions(+)
> >> > create mode 100644 Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt
> >> >
> >> > diff --git a/Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt b/Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt
> >> > new file mode 100644
> >> > index 000000000000..a246d59552b1
> >> > --- /dev/null
> >> > +++ b/Documentation/devicetree/bindings/interrupt-controller/marvell,sei.txt
> >> > @@ -0,0 +1,54 @@
> >> > +Marvell SEI (System Error Interrupt) Controller
> >> > +-----------------------------------------------
> >> > +
> >> > +Marvell SEI (System Error Interrupt) controller is an interrupt aggregator.
> >> > +It receives interrupts from several sources and aggregates them to a single
> >> > +interrupt line (an SPI) on the primary interrupt controller.
> >> > +
> >> > +The IRQ chip can handle up to 64 SEIs, a set comes from the AP and is
> >> > +wired while a second set comes from the CPs by the mean of MSIs. Each
> >> > +'domain' is represented as a subnode.
> >> > +
> >> > +Required properties:
> >> > +
> >> > +- compatible: should be "marvell,armada-8k-sei".
> >> > +- reg: SEI registers location and length.
> >> > +- interrupts: identifies the parent IRQ that will be triggered.
> >> > +- #address-cells: should be '1', represents the position of the first
> >> > + IRQ of a given type in the SEI range.
> >> > +- #size-cells: should be '1', represents the number of a given type of
> >> > + IRQs.
> >> > +
> >> > +Child node 'sei-wired-controller' required properties:
> >> > +
> >> > +- reg: the range of wired interrupts.
> >> > +- #interrupt-cells: number of cells to define an SEI wired interrupt
> >> > + coming from the AP, should be 1. The cell is the IRQ
> >> > + number.
> >> > +- interrupt-controller: identifies the node as an interrupt controller.
> >> > +
> >> > +Child node 'sei-msi-controller' required properties:
> >> > +
> >> > +- reg: the range of non-wired interrupts triggered by way of MSIs.
> >> > +- msi-controller: identifies the node as an MSI controller.
> >> > +
> >> > +Example:
> >> > +
> >> > + sei: sei at 3f0200 {
> >> > + compatible = "marvell,armada-8k-sei";
> >> > + reg = <0x3f0200 0x40>;
> >> > + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
> >> > + #address-cells = <1>;
> >> > + #size-cells = <1>;
> >> > +
> >> > + sei_wired_controller: sei-wired-controller at 0 {
> >> > + reg = <0 21>;
> >>
> >> Using interrupt numbers in reg is strange.
> >
> > I thought the reg property was the one to choose here, I can of course
> > change it, what would you suggest?
> >
> >>
> >> > + #interrupt-cells = <1>;
> >> > + interrupt-controller;
> >> > + };
> >> > +
> >> > + sei_msi_controller: sei-msi-controller at 21 {
> >> > + reg = <21 43>;
> >> > + msi-controller;
> >>
> >> Can't the parent be both an interrupt-controller and msi-controller?
I would prefer to describe how the hardware is split in two
sub-controllers. And to answer the question: no, the parent cannot be
both and interrupt-controller and an msi-controller.
> >
> > We need to know which one aggregates interrupts, which one receives
> > MSIs and most importantly which interrupt is what (within the 64
> > that are handled by the SEI).
>
> You mean that 0-20 are wired and 21-63 are msi? "marvell,msi-base =
> <21>;" in the parent would be sufficient for that though you may want
> something more flexible to have multiple ranges.
Absolutely, I would like something more flexible.
>
> It looks like there may already be similar bindings. See
> 'msi-available-ranges" and "{al,arm},msi-base-spi".
If you are ok, I will use a new property named 'marvell,sei-ranges'
instead of the reg property which is indeed more explicit.
Thanks,
Miqu?l
^ permalink raw reply
* [PATCH v3 3/3] arm64: dts: renesas: draak: Describe HDMI input
From: Jacopo Mondi @ 2018-05-18 14:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526654878-11143-1-git-send-email-jacopo+renesas@jmondi.org>
Describe HDMI input connector and ADV7612 HDMI decoder installed on
R-Car Gen3 Draak board.
The video signal routing to the HDMI decoder to the video input interface
VIN4 is multiplexed with CVBS input path, and enabled/disabled through
on-board switches SW-49, SW-50, SW-51 and SW-52.
As the default board switches configuration connects CVBS input to VIN4,
leave the HDMI decoder unconnected in DTS.
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Niklas S?derlund <niklas.soderlund+renesas@ragnatech.se>
---
v2 -> v3:
- Add comment on HDMI output port about the shared CVBS/HDMI video path
- Add Niklas' R-b tag
---
arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 48 ++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index 95745fc..1e475a4 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -59,6 +59,17 @@
};
};
+ hdmi-in {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&adv7612_in>;
+ };
+ };
+ };
+
memory at 48000000 {
device_type = "memory";
/* first 128MB is reserved for secure area. */
@@ -176,6 +187,43 @@
};
};
};
+
+ hdmi-decoder at 4c {
+ compatible = "adi,adv7612";
+ reg = <0x4c>;
+ default-input = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port at 0 {
+ reg = <0>;
+
+ adv7612_in: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+ };
+
+ port at 2 {
+ reg = <2>;
+
+ /*
+ * The VIN4 video input path is shared between
+ * CVBS and HDMI inputs through SW[49-54]
+ * switches.
+ *
+ * CVBS is the default selection, leave HDMI
+ * not connected here.
+ */
+ adv7612_out: endpoint {
+ pclk-sample = <0>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+ };
+ };
};
&i2c1 {
--
2.7.4
^ permalink raw reply related
* [PATCH v3 2/3] arm64: dts: renesas: draak: Describe CVBS input
From: Jacopo Mondi @ 2018-05-18 14:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526654878-11143-1-git-send-email-jacopo+renesas@jmondi.org>
Describe CVBS video input through analog video decoder ADV7180
connected to video input interface VIN4.
The video input signal path is shared with HDMI video input, and
selected by on-board switches SW-53 and SW-54 with CVBS input selected
by the default switches configuration.
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Niklas S?derlund <niklas.soderlund+renesas@ragnatech.se>
---
v2 -> v3:
- Add comment to describe the shared input video path
- Add my SoB and Niklas' R-b tags
---
arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 42 ++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index 9d73de8..95745fc 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -142,6 +142,11 @@
groups = "usb0";
function = "usb0";
};
+
+ vin4_pins_cvbs: vin4 {
+ groups = "vin4_data8", "vin4_sync", "vin4_clk";
+ function = "vin4";
+ };
};
&i2c0 {
@@ -154,6 +159,23 @@
reg = <0x50>;
pagesize = <8>;
};
+
+ analog-video at 20 {
+ compatible = "adi,adv7180";
+ reg = <0x20>;
+
+ port {
+ /*
+ * The VIN4 video input path is shared between
+ * CVBS and HDMI inputs through SW[49-54] switches.
+ *
+ * CVBS is the default selection, link it to VIN4 here.
+ */
+ adv7180_out: endpoint {
+ remote-endpoint = <&vin4_in>;
+ };
+ };
+ };
};
&i2c1 {
@@ -246,3 +268,23 @@
timeout-sec = <60>;
status = "okay";
};
+
+&vin4 {
+ pinctrl-0 = <&vin4_pins_cvbs>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port at 0 {
+ reg = <0>;
+
+ vin4_in: endpoint {
+ remote-endpoint = <&adv7180_out>;
+ };
+ };
+ };
+};
--
2.7.4
^ permalink raw reply related
* [PATCH v3 1/3] dt-bindings: media: rcar-vin: Add R8A77995 support
From: Jacopo Mondi @ 2018-05-18 14:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526654878-11143-1-git-send-email-jacopo+renesas@jmondi.org>
Add compatible string for R-Car D3 R8A7795 to list of SoCs supported by
rcar-vin driver.
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Acked-by: Niklas S?derlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
---
Documentation/devicetree/bindings/media/rcar_vin.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
index a19517e1..5c6f2a7 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -22,6 +22,7 @@ on Gen3 platforms to a CSI-2 receiver.
- "renesas,vin-r8a7795" for the R8A7795 device
- "renesas,vin-r8a7796" for the R8A7796 device
- "renesas,vin-r8a77970" for the R8A77970 device
+ - "renesas,vin-r8a77995" for the R8A77995 device
- "renesas,rcar-gen2-vin" for a generic R-Car Gen2 or RZ/G1 compatible
device.
--
2.7.4
^ permalink raw reply related
* [PATCH v3 0/3] arm64: dts: Draak: Enable video inputs and VIN4
From: Jacopo Mondi @ 2018-05-18 14:47 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
this series enables HDMI, CVBS and VIN4 for R8A77995 Draak board.
Compared to v2, I have added review tags and a missing Signed-off-by line.
Two small comments added to Draak DTS to describe the shared video input path
between CVBS and HDMI. As in v2, CVBS is the default video input and thus is
connected to VIN in DTS.
Switching to HDMI is shown in the patch on top of the following branch:
git://jmondi.org/linux d3/media-master/salvator-x-dts_csi2/d3-hdmi
Simon: once the series this one depends on [1] has been accepted, I guess this
one is ready to get in, right?
The series has been developed on top of media-master tree but applies cleanly
on top of latest renesas-driver.
Thanks
j
[1] [PATCH v3 0/9] rcar-vin: Add support for parallel input on Gen3
v2 -> v3:
- Add comment to CVBS and HDMI inputs
- Add missing Signed-off-by to [2/3]
- Add Niklas' tag
Jacopo Mondi (3):
dt-bindings: media: rcar-vin: Add R8A77995 support
arm64: dts: renesas: draak: Describe CVBS input
arm64: dts: renesas: draak: Describe HDMI input
.../devicetree/bindings/media/rcar_vin.txt | 1 +
arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 90 ++++++++++++++++++++++
2 files changed, 91 insertions(+)
--
2.7.4
^ permalink raw reply
* [PATCH v2 12/26] drm/sun4i: Add support for multiple DW HDMI PHY clock parents
From: Jernej Škrabec @ 2018-05-18 14:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518100116.4bf2qcffg7ekxa7u@flea>
Hi,
Dne petek, 18. maj 2018 ob 12:01:16 CEST je Maxime Ripard napisal(a):
> On Fri, May 18, 2018 at 03:15:22PM +0530, Jagan Teki wrote:
> > From: Jernej Skrabec <jernej.skrabec@siol.net>
> >
> > Some SoCs with DW HDMI have multiple possible clock parents, like A64
> > and R40.
> >
> > Expand HDMI PHY clock driver to support second clock parent.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> > ---
> > Changes for v2:
> > - new patch
> >
> > drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 9 ++-
> > drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 33 ++++++++---
> > drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 89
> > ++++++++++++++++++++++-------- 3 files changed, 96 insertions(+), 35
> > deletions(-)
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> > b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index 79154f0f674a..303189d6602c
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> > @@ -98,7 +98,8 @@
> >
> > #define SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN BIT(29)
> > #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN BIT(28)
> > #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 BIT(27)
> >
> > -#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL BIT(26)
> > +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK BIT(26)
> > +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT 26
> >
> > #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN BIT(25)
> > #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x) ((x) << 22)
> > #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x) ((x) << 20)
> >
> > @@ -146,7 +147,7 @@
> >
> > struct sun8i_hdmi_phy;
> >
> > struct sun8i_hdmi_phy_variant {
> >
> > - bool has_phy_clk;
> > + int phy_clk_num;
> >
> > void (*phy_init)(struct sun8i_hdmi_phy *phy);
> > void (*phy_disable)(struct dw_hdmi *hdmi,
> >
> > struct sun8i_hdmi_phy *phy);
> >
> > @@ -160,6 +161,7 @@ struct sun8i_hdmi_phy {
> >
> > struct clk *clk_mod;
> > struct clk *clk_phy;
> > struct clk *clk_pll0;
> >
> > + struct clk *clk_pll1;
> >
> > unsigned int rcal;
> > struct regmap *regs;
> > struct reset_control *rst_phy;
> >
> > @@ -188,6 +190,7 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi
> > *hdmi);
> >
> > void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
> > const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
> >
> > -int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
> > +int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
> > + int clk_num);
> >
> > #endif /* _SUN8I_DW_HDMI_H_ */
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 5a52fc489a9d..0eadf087fc46
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > @@ -183,7 +183,13 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi
> > *hdmi,>
> > regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
> >
> > SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK, 0);
> >
> > - regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, pll_cfg1_init);
> > + /*
> > + * NOTE: We have to be careful not to overwrite PHY parent
> > + * clock selection bit and clock divider.
> > + */
> > + regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
> > + (u32)~SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
> > + pll_cfg1_init);
> >
> > regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
> >
> > (u32)~SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
> > pll_cfg2_init);
> >
> > @@ -232,7 +238,7 @@ static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi,
> > void *data,>
> > regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
> >
> > SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK, val);
> >
> > - if (phy->variant->has_phy_clk)
> > + if (phy->variant->phy_clk_num)
> >
> > clk_set_rate(phy->clk_phy, mode->crtc_clock * 1000);
> >
> > return phy->variant->phy_config(hdmi, phy, mode->crtc_clock * 1000);
> >
> > @@ -393,7 +399,7 @@ static const struct sun8i_hdmi_phy_variant
> > sun8i_a83t_hdmi_phy = {>
> > };
> >
> > static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
> >
> > - .has_phy_clk = true,
> > + .phy_clk_num = 1,
> >
> > .phy_init = &sun8i_hdmi_phy_init_h3,
> > .phy_disable = &sun8i_hdmi_phy_disable_h3,
> > .phy_config = &sun8i_hdmi_phy_config_h3,
> >
> > @@ -464,7 +470,7 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi,
> > struct device_node *node)>
> > goto err_put_clk_bus;
> >
> > }
> >
> > - if (phy->variant->has_phy_clk) {
> > + if (phy->variant->phy_clk_num) {
> >
> > phy->clk_pll0 = of_clk_get_by_name(node, "pll-0");
> > if (IS_ERR(phy->clk_pll0)) {
> >
> > dev_err(dev, "Could not get pll-0 clock\n");
> >
> > @@ -472,7 +478,16 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi,
> > struct device_node *node)>
> > goto err_put_clk_mod;
> >
> > }
> >
> > - ret = sun8i_phy_clk_create(phy, dev);
> > + if (phy->variant->phy_clk_num) {
> > + phy->clk_pll1 = of_clk_get_by_name(node, "pll-1");
> > + if (IS_ERR(phy->clk_pll1)) {
> > + dev_err(dev, "Could not get pll-1 clock\n");
> > + ret = PTR_ERR(phy->clk_pll1);
> > + goto err_put_clk_mod;
> > + }
> > + }
> > +
>
> You have a bug here. If phy_clk_num == 1, you'll still try to lookup
> pll-1.
This is actually WIP patch taken from my github. This issue was fixed already
locally on disk. I thought Jagan will not use it until SRAM C patches land.
>
> And this is a bit sloppy, since if phy_clk_num == 3, you won't try to
> lookup pll-2 either.
It is highly unlikely this will be higher than 2, at least for this HDMI PHY,
since it has only 1 bit reserved for parent selection. But since I have to fix
it, I'll add ">= 2"
>
> > + ret = sun8i_phy_clk_create(phy, dev, phy->variant->phy_clk_num);
> >
> > if (ret) {
> >
> > dev_err(dev, "Couldn't create the PHY clock\n");
> > goto err_put_clk_pll0;
> >
> > @@ -515,8 +530,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi,
> > struct device_node *node)>
> > err_put_rst_phy:
> > reset_control_put(phy->rst_phy);
> >
> > err_put_clk_pll0:
> > - if (phy->variant->has_phy_clk)
> > - clk_put(phy->clk_pll0);
> > + clk_put(phy->clk_pll0);
> > + clk_put(phy->clk_pll1);
> >
> > err_put_clk_mod:
> > clk_put(phy->clk_mod);
> >
> > err_put_clk_bus:
> > @@ -536,8 +551,8 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
> >
> > reset_control_put(phy->rst_phy);
> >
> > - if (phy->variant->has_phy_clk)
> > - clk_put(phy->clk_pll0);
> > + clk_put(phy->clk_pll0);
> > + clk_put(phy->clk_pll1);
> >
> > clk_put(phy->clk_mod);
> > clk_put(phy->clk_bus);
> >
> > }
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
> > b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c index
> > faea449812f8..85b12fc96dbc 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
> > @@ -22,29 +22,36 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw
> > *hw,>
> > {
> >
> > unsigned long rate = req->rate;
> > unsigned long best_rate = 0;
> >
> > - struct clk_hw *parent;
> > + struct clk_hw *best_parent = NULL;
> > + struct clk_hw *parent = NULL;
> >
> > int best_div = 1;
> >
> > - int i;
> > + int i, p;
> >
> > - parent = clk_hw_get_parent(hw);
> > -
> > - for (i = 1; i <= 16; i++) {
> > - unsigned long ideal = rate * i;
> > - unsigned long rounded;
> > -
> > - rounded = clk_hw_round_rate(parent, ideal);
> > -
> > - if (rounded == ideal) {
> > - best_rate = rounded;
> > - best_div = i;
> > - break;
> > - }
> > + for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
> > + parent = clk_hw_get_parent_by_index(hw, p);
> > + if (!parent)
> > + continue;
> >
> > - if (!best_rate ||
> > - abs(rate - rounded / i) <
> > - abs(rate - best_rate / best_div)) {
> > - best_rate = rounded;
> > - best_div = i;
> > + for (i = 1; i <= 16; i++) {
> > + unsigned long ideal = rate * i;
> > + unsigned long rounded;
> > +
> > + rounded = clk_hw_round_rate(parent, ideal);
> > +
> > + if (rounded == ideal) {
> > + best_rate = rounded;
> > + best_div = i;
> > + best_parent = parent;
> > + break;
> > + }
> > +
> > + if (!best_rate ||
> > + abs(rate - rounded / i) <
> > + abs(rate - best_rate / best_div)) {
> > + best_rate = rounded;
> > + best_div = i;
> > + best_parent = parent;
> > + }
> >
> > }
> >
> > }
> >
> > @@ -95,22 +102,58 @@ static int sun8i_phy_clk_set_rate(struct clk_hw *hw,
> > unsigned long rate,>
> > return 0;
> >
> > }
> >
> > +static u8 sun8i_phy_clk_get_parent(struct clk_hw *hw)
> > +{
> > + struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
> > + u32 reg;
> > +
> > + regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, ®);
> > + reg = (reg & SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK) >>
> > + SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT;
> > +
> > + return reg;
> > +}
> > +
> > +static int sun8i_phy_clk_set_parent(struct clk_hw *hw, u8 index)
> > +{
> > + struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
> > +
> > + if (index > 1)
> > + return -EINVAL;
> > +
> > + regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
> > + SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
> > + index << SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT);
> > +
> > + return 0;
> > +}
> > +
>
> The DT bindings changes and the clk changes should be part of separate
> patches.
By DT bindings changes you mean code which reads DT and not DT documentation,
right?
Ok, I'll split it.
BTW, I'll resend fixed version of this patch for my R40 HDMI series, since
there is nothing to hold it back, unlike for this.
Best regards,
Jernej
^ permalink raw reply
* [PATCH v3 5/5] ARM: mach-virt: Select PMUv3 driver by default
From: Marc Zyngier @ 2018-05-18 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518143913.26306-1-marc.zyngier@arm.com>
Since 32bit guests are not unlikely to run on an ARMv8 host,
let's select the PMUv3 driver, which allows the PMU to be used
on such systems.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a7f8e7f4b88f..5dc5d5f15560 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -703,6 +703,7 @@ config ARCH_VIRT
select ARM_GIC_V3
select ARM_GIC_V3_ITS if PCI
select ARM_PSCI
+ select ARM_PMUV3 if PERF_EVENTS
select HAVE_ARM_ARCH_TIMER
#
--
2.14.2
^ permalink raw reply related
* [PATCH v3 4/5] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM
From: Marc Zyngier @ 2018-05-18 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518143913.26306-1-marc.zyngier@arm.com>
The only thing stopping the PMUv3 driver from compiling on 32bit
is the lack of defined system registers names. This is easily
solved by providing the sysreg accessors and updating the Kconfig entry.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/arm_pmuv3.h | 125 +++++++++++++++++++++++++++++++++++++++
drivers/perf/Kconfig | 4 +-
2 files changed, 127 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/include/asm/arm_pmuv3.h
diff --git a/arch/arm/include/asm/arm_pmuv3.h b/arch/arm/include/asm/arm_pmuv3.h
new file mode 100644
index 000000000000..e0f66c1d42b4
--- /dev/null
+++ b/arch/arm/include/asm/arm_pmuv3.h
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_PMUV3_H
+#define __ASM_PMUV3_H
+
+#include <asm/cp15.h>
+#include <asm/cputype.h>
+
+#define PMCCNTR __ACCESS_CP15_64(0, c9)
+
+#define PMCR __ACCESS_CP15(c9, 0, c12, 0)
+#define PMCNTENSET __ACCESS_CP15(c9, 0, c12, 1)
+#define PMCNTENCLR __ACCESS_CP15(c9, 0, c12, 2)
+#define PMOVSR __ACCESS_CP15(c9, 0, c12, 3)
+#define PMSELR __ACCESS_CP15(c9, 0, c12, 5)
+#define PMCEID0 __ACCESS_CP15(c9, 0, c12, 6)
+#define PMCEID1 __ACCESS_CP15(c9, 0, c12, 7)
+#define PMXEVTYPER __ACCESS_CP15(c9, 0, c13, 1)
+#define PMXEVCNTR __ACCESS_CP15(c9, 0, c13, 2)
+#define PMINTENSET __ACCESS_CP15(c9, 0, c14, 1)
+#define PMINTENCLR __ACCESS_CP15(c9, 0, c14, 2)
+
+static inline int read_pmuver(void)
+{
+ /* PMUVers is not a signed field */
+ u32 dfr0 = read_cpuid_ext(CPUID_EXT_DFR0);
+ return (dfr0 >> 24) & 0xf;
+}
+
+static inline void write_pmcr(u32 val)
+{
+ write_sysreg(val, PMCR);
+}
+
+static inline u32 read_pmcr(void)
+{
+ return read_sysreg(PMCR);
+}
+
+static inline void write_pmselr(u32 val)
+{
+ write_sysreg(val, PMSELR);
+}
+
+static inline void write_pmccntr(u64 val)
+{
+ write_sysreg(val, PMCCNTR);
+}
+
+static inline u64 read_pmccntr(void)
+{
+ return read_sysreg(PMCCNTR);
+}
+
+static inline void write_pmxevcntr(u32 val)
+{
+ write_sysreg(val, PMXEVCNTR);
+}
+
+static inline u32 read_pmxevcntr(void)
+{
+ return read_sysreg(PMXEVCNTR);
+}
+
+static inline void write_pmxevtyper(u32 val)
+{
+ write_sysreg(val, PMXEVTYPER);
+}
+
+static inline void write_pmcntenset(u32 val)
+{
+ write_sysreg(val, PMCNTENSET);
+}
+
+static inline void write_pmcntenclr(u32 val)
+{
+ write_sysreg(val, PMCNTENCLR);
+}
+
+static inline void write_pmintenset(u32 val)
+{
+ write_sysreg(val, PMINTENSET);
+}
+
+static inline void write_pmintenclr(u32 val)
+{
+ write_sysreg(val, PMINTENCLR);
+}
+
+static inline void write_pmovsclr(u32 val)
+{
+ write_sysreg(val, PMOVSR);
+}
+
+static inline u32 read_pmovsclr(void)
+{
+ return read_sysreg(PMOVSR);
+}
+
+static inline u32 read_pmceid0(void)
+{
+ return read_sysreg(PMCEID0);
+}
+
+static inline u32 read_pmceid1(void)
+{
+ return read_sysreg(PMCEID1);
+}
+
+#endif
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 39808b86b346..bf01dc1414c8 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -51,9 +51,9 @@ config ARM_PMU_ACPI
def_bool y
config ARM_PMUV3
- depends on HW_PERF_EVENTS && ARM64
+ depends on HW_PERF_EVENTS && ((ARM && CPU_V7) || ARM64)
bool "ARM PMUv3 support" if !ARM64
- default y
+ default ARM64
help
Say y if you want to use CPU performance monitors on ARMv8
systems that implement the PMUv3 architecture.
--
2.14.2
^ permalink raw reply related
* [PATCH v3 3/5] ARM: Make CONFIG_CPU_V7 valid for 32bit ARMv8 implementations
From: Marc Zyngier @ 2018-05-18 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518143913.26306-1-marc.zyngier@arm.com>
ARMv8 is a superset of ARMv7, and all the ARMv8 features are
discoverable with a set of ID registers. It means that we can
use CPU_V7 to guard ARMv8 features at compile time.
This commit simply amends the CPU_V7 configuration symbol comment
to reflect that CPU_V7 also covers ARMv8.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 7f14acf67caf..86550040de19 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -402,7 +402,7 @@ config CPU_V6K
select CPU_THUMB_CAPABLE
select CPU_TLB_V6 if MMU
-# ARMv7
+# ARMv7 and ARMv8 architectures
config CPU_V7
bool
select CPU_32v6K
--
2.14.2
^ permalink raw reply related
* [PATCH v3 2/5] arm64: perf: Abstract system register accesses away
From: Marc Zyngier @ 2018-05-18 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518143913.26306-1-marc.zyngier@arm.com>
As we want to enable 32bit support, we need to distanciate the
PMUv3 driver from the AArch64 system register names.
This patch moves all system register accesses to an architecture
specific include file, allowing the 32bit counterpart to be
slotted in at a later time.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/arm_pmuv3.h | 111 +++++++++++++++++++++++++++++++++++++
drivers/perf/arm_pmuv3.c | 40 ++++++-------
include/linux/perf/arm_pmuv3.h | 2 +
3 files changed, 131 insertions(+), 22 deletions(-)
create mode 100644 arch/arm64/include/asm/arm_pmuv3.h
diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h
new file mode 100644
index 000000000000..558ed16b0f70
--- /dev/null
+++ b/arch/arm64/include/asm/arm_pmuv3.h
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_PMUV3_H
+#define __ASM_PMUV3_H
+
+#include <asm/cpufeature.h>
+#include <asm/sysreg.h>
+
+static inline int read_pmuver(void)
+{
+ u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
+ return cpuid_feature_extract_unsigned_field(dfr0,
+ ID_AA64DFR0_PMUVER_SHIFT);
+}
+
+static inline void write_pmcr(u32 val)
+{
+ write_sysreg(val, pmcr_el0);
+}
+
+static inline u32 read_pmcr(void)
+{
+ return read_sysreg(pmcr_el0);
+}
+
+static inline void write_pmselr(u32 val)
+{
+ write_sysreg(val, pmselr_el0);
+}
+
+static inline void write_pmccntr(u64 val)
+{
+ write_sysreg(val, pmccntr_el0);
+}
+
+static inline u64 read_pmccntr(void)
+{
+ return read_sysreg(pmccntr_el0);
+}
+
+static inline void write_pmxevcntr(u32 val)
+{
+ write_sysreg(val, pmxevcntr_el0);
+}
+
+static inline u32 read_pmxevcntr(void)
+{
+ return read_sysreg(pmxevcntr_el0);
+}
+
+static inline void write_pmxevtyper(u32 val)
+{
+ write_sysreg(val, pmxevtyper_el0);
+}
+
+static inline void write_pmcntenset(u32 val)
+{
+ write_sysreg(val, pmcntenset_el0);
+}
+
+static inline void write_pmcntenclr(u32 val)
+{
+ write_sysreg(val, pmcntenclr_el0);
+}
+
+static inline void write_pmintenset(u32 val)
+{
+ write_sysreg(val, pmintenset_el1);
+}
+
+static inline void write_pmintenclr(u32 val)
+{
+ write_sysreg(val, pmintenclr_el1);
+}
+
+static inline void write_pmovsclr(u32 val)
+{
+ write_sysreg(val, pmovsclr_el0);
+}
+
+static inline u32 read_pmovsclr(void)
+{
+ return read_sysreg(pmovsclr_el0);
+}
+
+static inline u32 read_pmceid0(void)
+{
+ return read_sysreg(pmceid0_el0);
+}
+
+static inline u32 read_pmceid1(void)
+{
+ return read_sysreg(pmceid1_el0);
+}
+
+#endif
diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c
index bd19b16c44eb..9c7b2c10b52e 100644
--- a/drivers/perf/arm_pmuv3.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -22,7 +22,6 @@
#include <asm/irq_regs.h>
#include <asm/perf_event.h>
-#include <asm/sysreg.h>
#include <asm/virt.h>
#include <linux/acpi.h>
@@ -479,14 +478,14 @@ static struct attribute_group armv8_pmuv3_format_attr_group = {
static inline u32 armv8pmu_pmcr_read(void)
{
- return read_sysreg(pmcr_el0);
+ return read_pmcr();
}
static inline void armv8pmu_pmcr_write(u32 val)
{
val &= ARMV8_PMU_PMCR_MASK;
isb();
- write_sysreg(val, pmcr_el0);
+ write_pmcr(val);
}
static inline int armv8pmu_has_overflowed(u32 pmovsr)
@@ -508,7 +507,7 @@ static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx)
static inline int armv8pmu_select_counter(int idx)
{
u32 counter = ARMV8_IDX_TO_COUNTER(idx);
- write_sysreg(counter, pmselr_el0);
+ write_pmselr(counter);
isb();
return idx;
@@ -525,9 +524,9 @@ static inline u32 armv8pmu_read_counter(struct perf_event *event)
pr_err("CPU%u reading wrong counter %d\n",
smp_processor_id(), idx);
else if (idx == ARMV8_IDX_CYCLE_COUNTER)
- value = read_sysreg(pmccntr_el0);
+ value = read_pmccntr();
else if (armv8pmu_select_counter(idx) == idx)
- value = read_sysreg(pmxevcntr_el0);
+ value = read_pmxevcntr();
return value;
}
@@ -549,47 +548,47 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value)
*/
u64 value64 = 0xffffffff00000000ULL | value;
- write_sysreg(value64, pmccntr_el0);
+ write_pmccntr(value64);
} else if (armv8pmu_select_counter(idx) == idx)
- write_sysreg(value, pmxevcntr_el0);
+ write_pmxevcntr(value);
}
static inline void armv8pmu_write_evtype(int idx, u32 val)
{
if (armv8pmu_select_counter(idx) == idx) {
val &= ARMV8_PMU_EVTYPE_MASK;
- write_sysreg(val, pmxevtyper_el0);
+ write_pmxevtyper(val);
}
}
static inline int armv8pmu_enable_counter(int idx)
{
u32 counter = ARMV8_IDX_TO_COUNTER(idx);
- write_sysreg(BIT(counter), pmcntenset_el0);
+ write_pmcntenset(BIT(counter));
return idx;
}
static inline int armv8pmu_disable_counter(int idx)
{
u32 counter = ARMV8_IDX_TO_COUNTER(idx);
- write_sysreg(BIT(counter), pmcntenclr_el0);
+ write_pmcntenclr(BIT(counter));
return idx;
}
static inline int armv8pmu_enable_intens(int idx)
{
u32 counter = ARMV8_IDX_TO_COUNTER(idx);
- write_sysreg(BIT(counter), pmintenset_el1);
+ write_pmintenset(BIT(counter));
return idx;
}
static inline int armv8pmu_disable_intens(int idx)
{
u32 counter = ARMV8_IDX_TO_COUNTER(idx);
- write_sysreg(BIT(counter), pmintenclr_el1);
+ write_pmintenclr(BIT(counter));
isb();
/* Clear the overflow flag in case an interrupt is pending. */
- write_sysreg(BIT(counter), pmovsclr_el0);
+ write_pmovsclr(BIT(counter));
isb();
return idx;
@@ -600,11 +599,11 @@ static inline u32 armv8pmu_getreset_flags(void)
u32 value;
/* Read */
- value = read_sysreg(pmovsclr_el0);
+ value = read_pmovsclr();
/* Write to clear flags */
value &= ARMV8_PMU_OVSR_MASK;
- write_sysreg(value, pmovsclr_el0);
+ write_pmovsclr(value);
return value;
}
@@ -905,13 +904,10 @@ static void __armv8pmu_probe_pmu(void *info)
{
struct armv8pmu_probe_info *probe = info;
struct arm_pmu *cpu_pmu = probe->pmu;
- u64 dfr0;
u32 pmceid[2];
int pmuver;
- dfr0 = read_sysreg(id_aa64dfr0_el1);
- pmuver = cpuid_feature_extract_unsigned_field(dfr0,
- ID_AA64DFR0_PMUVER_SHIFT);
+ pmuver = read_pmuver();
if (pmuver == 0xf || pmuver == 0)
return;
@@ -924,8 +920,8 @@ static void __armv8pmu_probe_pmu(void *info)
/* Add the CPU cycles counter */
cpu_pmu->num_events += 1;
- pmceid[0] = read_sysreg(pmceid0_el0);
- pmceid[1] = read_sysreg(pmceid1_el0);
+ pmceid[0] = read_pmceid0();
+ pmceid[1] = read_pmceid1();
bitmap_from_arr32(cpu_pmu->pmceid_bitmap,
pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS);
diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h
index 131f486643bc..909188bd7db0 100644
--- a/include/linux/perf/arm_pmuv3.h
+++ b/include/linux/perf/arm_pmuv3.h
@@ -18,6 +18,8 @@
#ifndef __PERF_ARM_PMUV3_H
#define __PERF_ARM_PMUV3_H
+#include <asm/arm_pmuv3.h>
+
#define ARMV8_PMU_MAX_COUNTERS 32
#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1)
--
2.14.2
^ permalink raw reply related
* [PATCH v3 1/5] arm64: perf: Move PMUv3 driver to drivers/perf
From: Marc Zyngier @ 2018-05-18 14:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518143913.26306-1-marc.zyngier@arm.com>
Having the ARM PMUv3 driver sitting in arch/arm64/kernel is getting
in the way of being able to use perf on ARMv8 cores running a 32bit
kernel, such as 32bit KVM guests.
This patch moves it into drivers/perf/arm_pmuv3.c, with an include
file in include/linux/perf/arm_pmuv3.h. The only thing left in
arch/arm64 is some mundane perf stuff.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/perf_event.h | 55 ----------------
arch/arm64/kernel/Makefile | 1 -
drivers/perf/Kconfig | 8 +++
drivers/perf/Makefile | 1 +
.../perf_event.c => drivers/perf/arm_pmuv3.c | 2 +
include/kvm/arm_pmu.h | 2 +-
include/linux/perf/arm_pmuv3.h | 76 ++++++++++++++++++++++
7 files changed, 88 insertions(+), 57 deletions(-)
rename arch/arm64/kernel/perf_event.c => drivers/perf/arm_pmuv3.c (99%)
create mode 100644 include/linux/perf/arm_pmuv3.h
diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h
index f9ccc36d3dc3..5b33efeebabf 100644
--- a/arch/arm64/include/asm/perf_event.h
+++ b/arch/arm64/include/asm/perf_event.h
@@ -20,61 +20,6 @@
#include <asm/stack_pointer.h>
#include <asm/ptrace.h>
-#define ARMV8_PMU_MAX_COUNTERS 32
-#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1)
-
-/*
- * Per-CPU PMCR: config reg
- */
-#define ARMV8_PMU_PMCR_E (1 << 0) /* Enable all counters */
-#define ARMV8_PMU_PMCR_P (1 << 1) /* Reset all counters */
-#define ARMV8_PMU_PMCR_C (1 << 2) /* Cycle counter reset */
-#define ARMV8_PMU_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */
-#define ARMV8_PMU_PMCR_X (1 << 4) /* Export to ETM */
-#define ARMV8_PMU_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
-#define ARMV8_PMU_PMCR_LC (1 << 6) /* Overflow on 64 bit cycle counter */
-#define ARMV8_PMU_PMCR_N_SHIFT 11 /* Number of counters supported */
-#define ARMV8_PMU_PMCR_N_MASK 0x1f
-#define ARMV8_PMU_PMCR_MASK 0x7f /* Mask for writable bits */
-
-/*
- * PMOVSR: counters overflow flag status reg
- */
-#define ARMV8_PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */
-#define ARMV8_PMU_OVERFLOWED_MASK ARMV8_PMU_OVSR_MASK
-
-/*
- * PMXEVTYPER: Event selection reg
- */
-#define ARMV8_PMU_EVTYPE_MASK 0xc800ffff /* Mask for writable bits */
-#define ARMV8_PMU_EVTYPE_EVENT 0xffff /* Mask for EVENT bits */
-
-/*
- * PMUv3 event types: required events
- */
-#define ARMV8_PMUV3_PERFCTR_SW_INCR 0x00
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x03
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x04
-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x10
-#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x11
-#define ARMV8_PMUV3_PERFCTR_BR_PRED 0x12
-
-/*
- * Event filters for PMUv3
- */
-#define ARMV8_PMU_EXCLUDE_EL1 (1 << 31)
-#define ARMV8_PMU_EXCLUDE_EL0 (1 << 30)
-#define ARMV8_PMU_INCLUDE_EL2 (1 << 27)
-
-/*
- * PMUSERENR: user enable reg
- */
-#define ARMV8_PMU_USERENR_MASK 0xf /* Mask for writable bits */
-#define ARMV8_PMU_USERENR_EN (1 << 0) /* PMU regs can be accessed at EL0 */
-#define ARMV8_PMU_USERENR_SW (1 << 1) /* PMSWINC can be written at EL0 */
-#define ARMV8_PMU_USERENR_CR (1 << 2) /* Cycle counter can be read at EL0 */
-#define ARMV8_PMU_USERENR_ER (1 << 3) /* Event counter can be read@EL0 */
-
#ifdef CONFIG_PERF_EVENTS
struct pt_regs;
extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index bf825f38d206..aba9344a72ca 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -32,7 +32,6 @@ arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o
arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
-arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
arm64-obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a029558..39808b86b346 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -50,6 +50,14 @@ config ARM_PMU_ACPI
depends on ARM_PMU && ACPI
def_bool y
+config ARM_PMUV3
+ depends on HW_PERF_EVENTS && ARM64
+ bool "ARM PMUv3 support" if !ARM64
+ default y
+ help
+ Say y if you want to use CPU performance monitors on ARMv8
+ systems that implement the PMUv3 architecture.
+
config ARM_DSU_PMU
tristate "ARM DynamIQ Shared Unit (DSU) PMU"
depends on ARM64
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index b3902bd37d53..a1a2f64e0c8f 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_ARM_CCN) += arm-ccn.o
obj-$(CONFIG_ARM_DSU_PMU) += arm_dsu_pmu.o
obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o
obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
+obj-$(CONFIG_ARM_PMUV3) += arm_pmuv3.o
obj-$(CONFIG_HISI_PMU) += hisilicon/
obj-$(CONFIG_QCOM_L2_PMU) += qcom_l2_pmu.o
obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o
diff --git a/arch/arm64/kernel/perf_event.c b/drivers/perf/arm_pmuv3.c
similarity index 99%
rename from arch/arm64/kernel/perf_event.c
rename to drivers/perf/arm_pmuv3.c
index 85a251b6dfa8..bd19b16c44eb 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PMU support
*
@@ -27,6 +28,7 @@
#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/perf/arm_pmu.h>
+#include <linux/perf/arm_pmuv3.h>
#include <linux/platform_device.h>
/*
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index f87fe20fcb05..d16ce92cb2c0 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -19,7 +19,7 @@
#define __ASM_ARM_KVM_PMU_H
#include <linux/perf_event.h>
-#include <asm/perf_event.h>
+#include <linux/perf/arm_pmuv3.h>
#define ARMV8_PMU_CYCLE_IDX (ARMV8_PMU_MAX_COUNTERS - 1)
diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h
new file mode 100644
index 000000000000..131f486643bc
--- /dev/null
+++ b/include/linux/perf/arm_pmuv3.h
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PERF_ARM_PMUV3_H
+#define __PERF_ARM_PMUV3_H
+
+#define ARMV8_PMU_MAX_COUNTERS 32
+#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1)
+
+/*
+ * Per-CPU PMCR: config reg
+ */
+#define ARMV8_PMU_PMCR_E (1 << 0) /* Enable all counters */
+#define ARMV8_PMU_PMCR_P (1 << 1) /* Reset all counters */
+#define ARMV8_PMU_PMCR_C (1 << 2) /* Cycle counter reset */
+#define ARMV8_PMU_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */
+#define ARMV8_PMU_PMCR_X (1 << 4) /* Export to ETM */
+#define ARMV8_PMU_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
+#define ARMV8_PMU_PMCR_LC (1 << 6) /* Overflow on 64 bit cycle counter */
+#define ARMV8_PMU_PMCR_N_SHIFT 11 /* Number of counters supported */
+#define ARMV8_PMU_PMCR_N_MASK 0x1f
+#define ARMV8_PMU_PMCR_MASK 0x7f /* Mask for writable bits */
+
+/*
+ * PMOVSR: counters overflow flag status reg
+ */
+#define ARMV8_PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */
+#define ARMV8_PMU_OVERFLOWED_MASK ARMV8_PMU_OVSR_MASK
+
+/*
+ * PMXEVTYPER: Event selection reg
+ */
+#define ARMV8_PMU_EVTYPE_MASK 0xc800ffff /* Mask for writable bits */
+#define ARMV8_PMU_EVTYPE_EVENT 0xffff /* Mask for EVENT bits */
+
+/*
+ * PMUv3 event types: required events
+ */
+#define ARMV8_PMUV3_PERFCTR_SW_INCR 0x00
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x03
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x04
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x10
+#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x11
+#define ARMV8_PMUV3_PERFCTR_BR_PRED 0x12
+
+/*
+ * Event filters for PMUv3
+ */
+#define ARMV8_PMU_EXCLUDE_EL1 (1 << 31)
+#define ARMV8_PMU_EXCLUDE_EL0 (1 << 30)
+#define ARMV8_PMU_INCLUDE_EL2 (1 << 27)
+
+/*
+ * PMUSERENR: user enable reg
+ */
+#define ARMV8_PMU_USERENR_MASK 0xf /* Mask for writable bits */
+#define ARMV8_PMU_USERENR_EN (1 << 0) /* PMU regs can be accessed at EL0 */
+#define ARMV8_PMU_USERENR_SW (1 << 1) /* PMSWINC can be written at EL0 */
+#define ARMV8_PMU_USERENR_CR (1 << 2) /* Cycle counter can be read at EL0 */
+#define ARMV8_PMU_USERENR_ER (1 << 3) /* Event counter can be read@EL0 */
+
+#endif
--
2.14.2
^ permalink raw reply related
* [PATCH v3 0/5]
From: Marc Zyngier @ 2018-05-18 14:39 UTC (permalink / raw)
To: linux-arm-kernel
PMUv3 has been introduced with ARMv8 and, while it has only been used
on 64bit systems so far, it would definitely be useful for 32bit
guests running under KVM/arm64, for example.
There is also the case of people natively running 32bit kernels on
64bit HW and trying to upstream unspeakable hacks, hoping that the
stars will align and that they'll win the lottery (see [1]).
So let's try again, and make the PMUv3 driver usable for everyone.
This is done in three steps:
(1) Move the driver from arch/arm64 to drivers/perf
(2) Add a handful of system register accessors so that we can reuse
the driver on 32bit
(3) Provide the same accessors on 32bit, enable compilation, and
make it the default selection for mach-virt.
Tested on a Seattle box with 32bit guests.
* From v1:
- Fixed encodings for some CP15 accessors
- Added a terse note saying that CPU_V7 also covers ARMv8
- Rebased on v4.12-rc5
* From v2:
- SPDX tags on new and moved files. Yeah!
- Annual rebase on 4.17-rc5
[1] https://patchwork.kernel.org/patch/10406793/
Marc Zyngier (5):
arm64: perf: Move PMUv3 driver to drivers/perf
arm64: perf: Abstract system register accesses away
ARM: Make CONFIG_CPU_V7 valid for 32bit ARMv8 implementations
ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM
ARM: mach-virt: Select PMUv3 driver by default
arch/arm/Kconfig | 1 +
arch/arm/include/asm/arm_pmuv3.h | 125 +++++++++++++++++++++
arch/arm/mm/Kconfig | 2 +-
arch/arm64/include/asm/arm_pmuv3.h | 111 ++++++++++++++++++
arch/arm64/include/asm/perf_event.h | 55 ---------
arch/arm64/kernel/Makefile | 1 -
drivers/perf/Kconfig | 8 ++
drivers/perf/Makefile | 1 +
.../perf_event.c => drivers/perf/arm_pmuv3.c | 42 ++++---
include/kvm/arm_pmu.h | 2 +-
include/linux/perf/arm_pmuv3.h | 78 +++++++++++++
11 files changed, 346 insertions(+), 80 deletions(-)
create mode 100644 arch/arm/include/asm/arm_pmuv3.h
create mode 100644 arch/arm64/include/asm/arm_pmuv3.h
rename arch/arm64/kernel/perf_event.c => drivers/perf/arm_pmuv3.c (97%)
create mode 100644 include/linux/perf/arm_pmuv3.h
--
2.14.2
^ permalink raw reply
* [PATCH v7 1/2] dt-bindings: Documentation for qcom, llcc
From: Rob Herring @ 2018-05-18 14:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526492623-20527-2-git-send-email-rishabhb@codeaurora.org>
On Wed, May 16, 2018 at 10:43:42AM -0700, Rishabh Bhatnagar wrote:
> Documentation for last level cache controller device tree bindings,
> client bindings usage examples.
>
> Signed-off-by: Channagoud Kadabi <ckadabi@codeaurora.org>
> Signed-off-by: Rishabh Bhatnagar <rishabhb@codeaurora.org>
> ---
> .../devicetree/bindings/arm/msm/qcom,llcc.txt | 26 ++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
Other than the node name discussed in v6,
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH 4/4] omap4-droid4: Use software debounce for gpio-keys
From: Tony Lindgren @ 2018-05-18 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518072109.GA31304@amd>
* Pavel Machek <pavel@ucw.cz> [180518 07:23]:
> BTW, did you notice that debouncing is wrong on most of the keyboard?
> If you double click a key (most will do, for example "J") it will fail
> to recognize second release and instead of expected "jj", you get
> autorepeat ("jjjjjjjjjjjjjjjjjjjjjj...").
Hmm OK I have not seen that one.
> Ok, I guess main keyboard is not on GPIO...
No it's using omap4-keypad.c.
> > @@ -128,6 +128,7 @@
> > gpios = <&gpio5 26 GPIO_ACTIVE_LOW>; /* gpio154 */
> > linux,code = <KEY_VOLUMEDOWN>;
> > linux,can-disable;
> > + debounce-interval = <10>;
>
> I'd say this subtlety is worth a comment.
Good idea, I'll add a comment "Value above 7.95ms for no GPIO hardware
debounce". I'll do it also for duovero.
Regards,
Tony
^ permalink raw reply
* [PATCH v6 1/2] dt-bindings: Documentation for qcom, llcc
From: Rob Herring @ 2018-05-18 14:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <079348edcb511cefb9f4d76877d50cb7@codeaurora.org>
On Wed, May 16, 2018 at 04:32:27PM -0700, rishabhb at codeaurora.org wrote:
> On 2018-05-16 11:08, Stephen Boyd wrote:
> > Quoting rishabhb at codeaurora.org (2018-05-16 10:33:14)
> > > On 2018-05-16 10:03, Stephen Boyd wrote:
> > > > Quoting Rishabh Bhatnagar (2018-05-08 13:22:00)
> > >
> > > >> +
> > > >> +- max-slices:
> > > >> + usage: required
> > > >> + Value Type: <u32>
> > > >> + Definition: Number of cache slices supported by hardware
> > > >> +
> > > >> +Example:
> > > >> +
> > > >> + llcc: qcom,llcc at 1100000 {
> > > >
> > > > cache-controller at 1100000 ?
> > > >
> > > We have tried to use consistent naming convention as in llcc_*
> > > everywhere.
> > > Using cache-controller will mix and match the naming convention.
> > > Also in
> > > the documentation it is explained what llcc is and its full form.
> > >
> >
> > DT prefers standard node names as opposed to vendor specific node names.
> > Isn't it a cache controller? I fail to see why this can't be done.
> Hi Stephen,
> The driver is vendor specific and also for uniformity purposes we preferred
> to go with this name.
Almost *every* node and driver is vendor specific. Please do as Stephen
suggested.
Rob
^ permalink raw reply
* [PATCH v2 1/6] spi: sun6i: coding style/readability improvements
From: Maxime Ripard @ 2018-05-18 14:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180517070307.GP20254@sirena.org.uk>
Hi,
On Thu, May 17, 2018 at 04:03:07PM +0900, Mark Brown wrote:
> On Fri, Mar 30, 2018 at 03:50:42PM +0300, Sergey Suloev wrote:
> > Minor changes to fulfill the coding style and improve
> > the readability of the code.
> >
> > Changes in v2:
> > 1) Fixed issue with misplacing a piece of code that requires access
> > to the transfer structure into sun6i_spi_prepare_message() function
> > where the transfer structure is not available.
>
> Place inter-version changelogs after the --- as covered in
> SubmittingPatches.
>
> >
> > Signed-off-by: Sergey Suloev <ssuloev@orpaltech.com>
> >
> > ---
> > drivers/spi/spi-sun6i.c | 97 +++++++++++++++++++++++++++++--------------------
>
> This is a *very* large change doing a whole bunch of different things,
> including some fairly substantial changes like moving things into
> different functions but the changelog doesn't provide any details at all
> on what the changes are supposed to be. This makes it difficult to
> review, it should be split into separate patches each doing one clerly
> described thing (I'm guessing this might be part of why the AllWinner
> maintainers haven't reviewed the series).
We didn't really review them because most of the changes done here
were also applicable to the sun4i series that was sent pretty much at
the same time:
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/570056.html
We should have made that clearer, sorry.
Maxime
--
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180518/00ba89c6/attachment.sig>
^ permalink raw reply
* [PATCH v8 11/15] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu
From: Rob Herring @ 2018-05-18 14:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526555955-29960-12-git-send-email-ilialin@codeaurora.org>
On Thu, May 17, 2018 at 02:19:11PM +0300, Ilia Lin wrote:
> The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
> to provide the OPP framework with required information.
> This is used to determine the voltage and frequency value for each OPP of
> operating-points-v2 table when it is parsed by the OPP framework.
>
> This change adds documentation for the DT bindings.
> The "operating-points-v2-kryo-cpu" DT extends the "operating-points-v2"
> with following parameters:
> - nvmem-cells (NVMEM area containig the speedbin information)
> - opp-supported-hw: A single 32 bit bitmap value,
> representing compatible HW:
> 0: MSM8996 V3, speedbin 0
> 1: MSM8996 V3, speedbin 1
> 2: MSM8996 V3, speedbin 2
> 3: unused
> 4: MSM8996 SG, speedbin 0
> 5: MSM8996 SG, speedbin 1
> 6: MSM8996 SG, speedbin 2
> 7-31: unused
>
> Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> .../devicetree/bindings/opp/kryo-cpufreq.txt | 680 +++++++++++++++++++++
> 1 file changed, 680 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/opp/kryo-cpufreq.txt
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH v10 24/27] dt-bindings: timer: new bindings for TI DaVinci timer
From: Rob Herring @ 2018-05-18 14:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180509172606.29387-25-david@lechnology.com>
On Wed, May 09, 2018 at 12:26:03PM -0500, David Lechner wrote:
> This adds new device tree bindings for the timer IP block of TI
> DaVinci-like SoCs.
>
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
>
> v10 changes:
> - changed compatible to "ti,da830-timer"
> - added interrupts and interrupt-names properties
> - fixed grammatical error
>
> v9 changes:
> - new patch in v9
>
>
> .../bindings/timer/ti,davinci-timer.txt | 37 +++++++++++++++++++
> 1 file changed, 37 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/timer/ti,davinci-timer.txt
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH v2 16/26] dt-bindings: clock: sun50i-a64-ccu: Add PLL_VIDEO[0-1] macros
From: Rob Herring @ 2018-05-18 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518094536.17201-17-jagan@amarulasolutions.com>
On Fri, May 18, 2018 at 03:15:26PM +0530, Jagan Teki wrote:
> Allwinner A64 has two clock parents PLL_VIDEO0 and PLL_VIDEO1.
>
> Include these macros on dt-bindings so-that the same can be
> used while defining CCU clock phadles.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> ---
> Changes for v2:
> - new patch
>
> include/dt-bindings/clock/sun50i-a64-ccu.h | 2 ++
> 1 file changed, 2 insertions(+)
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [GIT PULL 5/5] arm64: tegra: Device tree changes for v4.18-rc1
From: Thierry Reding @ 2018-05-18 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-1-thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-arm64-dt
for you to fetch changes up to 9df50ba76ac1485b844beffa1f3f5d9659d9cdaf:
arm64: tegra: Make BCM89610 PHY interrupt as active low (2018-05-03 11:48:16 +0200)
I already sent this out as a fix for v4.17, so if you decide to pick
that up you can ignore this one. I've only included it here in case you
had objections to take it into v4.17 at this point.
Thanks,
Thierry
----------------------------------------------------------------
arm64: tegra: Device tree changes for v4.18-rc1
Contains a single fix for the network PHY interrupt polarity.
----------------------------------------------------------------
Bhadram Varka (1):
arm64: tegra: Make BCM89610 PHY interrupt as active low
arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
^ permalink raw reply
* [GIT PULL 4/5] ARM: tegra: Device tree changes for v4.18-rc1
From: Thierry Reding @ 2018-05-18 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-1-thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-arm-dt
for you to fetch changes up to dc4ea601be724d7ad37c8c5b1059417126e97e27:
ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients (2018-05-04 17:21:02 +0200)
Thanks,
Thierry
----------------------------------------------------------------
ARM: tegra: Device tree changes for v4.18-rc1
Contains a fix for the high-speed UART on Toradex Apalis TK1 boards as
well as IOMMU enablement for various devices on Tegra30 and Tegra30.
----------------------------------------------------------------
Dmitry Osipenko (2):
ARM: dts: tegra30: Add IOMMU nodes to Host1x and its clients
ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients
Marcel Ziswiler (1):
ARM: tegra: apalis-tk1: Fix high speed UART compatible
arch/arm/boot/dts/tegra114.dtsi | 5 +++++
arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi | 6 +++---
arch/arm/boot/dts/tegra124-apalis.dtsi | 6 +++---
arch/arm/boot/dts/tegra30.dtsi | 14 ++++++++++++++
4 files changed, 25 insertions(+), 6 deletions(-)
^ permalink raw reply
* [GIT PULL 3/5] ARM: tegra: Core changes for v4.18-rc1
From: Thierry Reding @ 2018-05-18 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-1-thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-arm-soc
for you to fetch changes up to 15164e0072b579f77c9025f3da3ed931869b89cd:
ARM: tegra: Create platform device for tegra20-cpufreq driver (2018-05-18 11:15:42 +0200)
Thanks,
Thierry
----------------------------------------------------------------
ARM: tegra: Core changes for v4.18-rc1
Contains a single patch that instantiates a platform device for the CPU
frequency driver.
----------------------------------------------------------------
Dmitry Osipenko (1):
ARM: tegra: Create platform device for tegra20-cpufreq driver
arch/arm/mach-tegra/tegra.c | 4 ++++
1 file changed, 4 insertions(+)
^ permalink raw reply
* [GIT PULL 2/5] memory: tegra: Changes for v4.18-rc1
From: Thierry Reding @ 2018-05-18 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518142245.20242-1-thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.18-memory
for you to fetch changes up to bef89a8d81ca97aca864778746b110cf52847868:
memory: tegra: Remove Tegra114 SATA and AFI reset definitions (2018-05-18 12:33:02 +0200)
Thanks,
Thierry
----------------------------------------------------------------
memory: tegra: Changes for v4.18-rc1
This contains some cleanup of the memory controller driver as well as
unification work to share more code between Tegra20 and later SoC
generations. Also included are an implementation for the hot resets
functionality by the memory controller which is required to properly
reset busy hardware.
----------------------------------------------------------------
Dmitry Osipenko (14):
dt-bindings: memory: tegra: Add hot resets definitions
memory: tegra: Do not handle spurious interrupts
memory: tegra: Setup interrupts mask before requesting IRQ
memory: tegra: Apply interrupts mask per SoC
memory: tegra: Remove unused headers inclusions
memory: tegra: Squash tegra20-mc into common tegra-mc driver
memory: tegra: Introduce memory client hot reset
memory: tegra: Add Tegra20 memory controller hot resets
memory: tegra: Add Tegra30 memory controller hot resets
memory: tegra: Add Tegra114 memory controller hot resets
memory: tegra: Add Tegra124 memory controller hot resets
memory: tegra: Register SMMU after MC driver became ready
dt-bindings: memory: tegra: Remove Tegra114 SATA and AFI reset definitions
memory: tegra: Remove Tegra114 SATA and AFI reset definitions
Thierry Reding (1):
memory: tegra: Add Tegra210 memory controller hot resets
drivers/memory/Kconfig | 10 -
drivers/memory/Makefile | 1 -
drivers/memory/tegra/Makefile | 1 +
drivers/memory/tegra/mc.c | 362 +++++++++++++++++++++++++++----
drivers/memory/tegra/mc.h | 22 ++
drivers/memory/tegra/tegra114.c | 33 +++
drivers/memory/tegra/tegra124.c | 48 ++++
drivers/memory/tegra/tegra20.c | 296 +++++++++++++++++++++++++
drivers/memory/tegra/tegra210.c | 53 ++++-
drivers/memory/tegra/tegra30.c | 35 +++
drivers/memory/tegra20-mc.c | 254 ----------------------
include/dt-bindings/memory/tegra114-mc.h | 17 ++
include/dt-bindings/memory/tegra124-mc.h | 25 +++
include/dt-bindings/memory/tegra20-mc.h | 21 ++
include/dt-bindings/memory/tegra210-mc.h | 31 +++
include/dt-bindings/memory/tegra30-mc.h | 19 ++
include/soc/tegra/mc.h | 37 +++-
17 files changed, 956 insertions(+), 309 deletions(-)
create mode 100644 drivers/memory/tegra/tegra20.c
delete mode 100644 drivers/memory/tegra20-mc.c
create mode 100644 include/dt-bindings/memory/tegra20-mc.h
^ 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