* Re: [PATCH v3 6/6] interconnect: Add OPP table support for interconnects
From: Vincent Guittot @ 2019-07-24 7:16 UTC (permalink / raw)
To: Saravana Kannan
Cc: Georgi Djakov, Rob Herring, Mark Rutland, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Sweeney, Sean,
daidavid1, Rajendra Nayak, sibis, Bjorn Andersson, Evan Green,
Android Kernel Team, open list:THERMAL,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-kernel
In-Reply-To: <CAGETcx_w=yVDiwVWT1+mmoj54FuLC37Eh2E-s0BfrtEa0AqEjw@mail.gmail.com>
On Tue, 16 Jul 2019 at 02:56, Saravana Kannan <saravanak@google.com> wrote:
>
> On Mon, Jul 15, 2019 at 1:16 AM Vincent Guittot
> <vincent.guittot@linaro.org> wrote:
> >
> > On Tue, 9 Jul 2019 at 21:03, Saravana Kannan <saravanak@google.com> wrote:
> > >
> > > On Tue, Jul 9, 2019 at 12:25 AM Vincent Guittot
> > > <vincent.guittot@linaro.org> wrote:
> > > >
> > > > On Sun, 7 Jul 2019 at 23:48, Saravana Kannan <saravanak@google.com> wrote:
> > > > >
> > > > > On Thu, Jul 4, 2019 at 12:12 AM Vincent Guittot
> > > > > <vincent.guittot@linaro.org> wrote:
> > > > > >
> > > > > > On Wed, 3 Jul 2019 at 23:33, Saravana Kannan <saravanak@google.com> wrote:
> > > > > > >
> > > > > > > On Tue, Jul 2, 2019 at 11:45 PM Vincent Guittot
> > > > > > > <vincent.guittot@linaro.org> wrote:
> > > > > > > >
> > > > > > > > On Wed, 3 Jul 2019 at 03:10, Saravana Kannan <saravanak@google.com> wrote:
> > > > > > > > >
> > > > > > > > > Interconnect paths can have different performance points. Now that OPP
> > > > > > > > > framework supports bandwidth OPP tables, add OPP table support for
> > > > > > > > > interconnects.
> > > > > > > > >
> > > > > > > > > Devices can use the interconnect-opp-table DT property to specify OPP
> > > > > > > > > tables for interconnect paths. And the driver can obtain the OPP table for
> > > > > > > > > an interconnect path by calling icc_get_opp_table().
> > > > > > > >
> > > > > > > > The opp table of a path must come from the aggregation of OPP tables
> > > > > > > > of the interconnect providers.
> > > > > > >
> > > > > > > The aggregation of OPP tables of the providers is certainly the
> > > > > > > superset of what a path can achieve, but to say that OPPs for
> > > > > > > interconnect path should match that superset is an oversimplification
> > > > > > > of the reality in hardware.
> > > > > > >
> > > > > > > There are lots of reasons an interconnect path might not want to use
> > > > > > > all the available bandwidth options across all the interconnects in
> > > > > > > the route.
> > > > > > >
> > > > > > > 1. That particular path might not have been validated or verified
> > > > > > > during the HW design process for some of the frequencies/bandwidth
> > > > > > > combinations of the providers.
> > > > > >
> > > > > > All these constraint are provider's constraints and not consumer's one
> > > > > >
> > > > > > The consumer asks for a bandwidth according to its needs and then the
> > > > > > providers select the optimal bandwidth of each interconnect after
> > > > > > aggregating all the request and according to what OPP have been
> > > > > > validated
> > > > >
> > > > > Not really. The screening can be a consumer specific issue. The
> > > > > consumer IP itself might have some issue with using too low of a
> > > > > bandwidth or bandwidth that's not within some range. It should not be
> > > >
> > > > How can an IP ask for not enough bandwidth ?
> > > > It asks the needed bandwidth based on its requirements
> > >
> > > The "enough bandwidth" is not always obvious. It's only for very
> > > simple cases that you can calculate the required bandwidth. Even for
> > > cases that you think might be "obvious/easy" aren't always easy.
> > >
> > > For example, you'd think a display IP would have a fixed bandwidth
> > > requirement for a fixed resolution screen. But that's far from the
> > > truth. It can also change as the number of layers change per frame.
> > > For video decoder/encoder, it depends on how well the frames compress
> > > with a specific compression scheme.
> > > So the "required" bandwidth is often a heuristic based on the IP
> > > frequency or traffic measurement.
> > >
> > > But that's not even the point I was making in this specific "bullet".
> > >
> > > A hardware IP might be screen/verified with only certain bandwidth
> > > levels. Or it might have hardware bugs that prevent it from using
> > > lower bandwidths even though it's technically sufficient. We need a
> > > way to capture that per path. This is not even a fictional case. This
> > > has been true multiple times over widely used IPs.
> >
> > here you are mixing HW constraint on the soc and OPP screening with
> > bandwidth request from consumer
> > ICC framework is about getting bandwidth request not trying to fix
> > some HW/voltage dependency of the SoC
> >
> > >
> > > > > the provider's job to take into account all the IP that might be
> > > > > connected to the interconnects. If the interconnect HW itself didn't
> > > >
> > > > That's not what I'm saying. The provider knows which bandwidth the
> > > > interconnect can provide as it is the ones which configures it. So if
> > > > the interconnect has a finite number of bandwidth point based probably
> > > > on the possible clock frequency and others config of the interconnect,
> > > > it selects the best final config after aggregating the request of the
> > > > consumer.
> > >
> > > I completely agree with this. What you are stating above is how it
> > > should work and that's the whole point of the interconnect framework.
> > >
> > > But this is orthogonal to the point I'm making.
> >
> > It's not orthogonal because you want to add a OPP table pointer in the
> > ICC path structure to fix your platform HW constraint whereas it's not
> > the purpose of the framework IMO
> >
> > >
> > > > > change, the provider driver shouldn't need to change. By your
> > > > > definition, a provider driver will have to account for all the
> > > > > possible bus masters that might be connected to it across all SoCs.
> > > >
> > > > you didn't catch my point
> > >
> > > Same. I think we are talking over each other. Let me try again.
> > >
> > > You are trying to describe how and interconnect provider and framework
> > > should work. There's no disagreement there.
> > >
> > > My point is that consumers might not want to or can not always use all
> > > the available bandwidth levels offered by the providers. There can be
> > > many reasons for that (which is what I listed in my earlier emails)
> > > and we need a good and generic way to capture that so that everyone
> > > isn't trying to invent their own property.
> >
> > And my point is that you want to describe some platform or even UCs
> > specific constraint in the ICC framework which is not the place to do.
> >
> > If the consumers might not want to use all available bandwidth because
> > this is not power efficient as an example, this should be describe
> > somewhere else to express that there is a shared power domain
> > between some devices and we shoudl ensure that all devices in this
> > power domain should use the Optimal Operating Point (optimal freq for
> > a voltage)
>
> My patch series has nothing to do with shared power domains. I think
> the examples have made it amply clear.
It's far from being clear why a consumer doesn't want to use some
bandwidth level TBH
Do you have a real example ?
>
> > ICC framework describes the bandwidth request that are expressed by
> > the consumers for the current running state of their IP but it doesn't
> > reflect the fact that on platform A, the consumer should use bandwidth
> > X because it will select a voltage level of a shared power domain that
> > is optimized for the other devices B, C ... . It's up to the provider
> > to know HW details of the bus that it drives and to make such
> > decision; the consumer should always request the same
>
> The change to ICC framework is practically just this. I don't have any
> future changes planned for the ICC framework. This is the entirety of
> it.
>
> + opp_node = of_parse_phandle(np, "interconnect-opp-table", idx);
> + if (opp_node) {
> + path->opp_table = dev_pm_opp_of_find_table_from_node(opp_node);
> + of_node_put(opp_node);
> + }
>
> It's quite a stretch and bit hyperbolic to say this one change is
> getting ICC framework to do all the things you claim above.
>
So I clearly don't see the benefit of adding this opp_table field in
icc_path struct because I'm still convinced that the consumer doesn't
have to get a bandwidth table like that.
If the consumer already get a bandwidth value and it should in order
to call icc_set or even in order to select one element in your table,
then it should directly set it with icc_set and let the provider
aggregate and choose the real one
> It's literally a simple helper function so that the consumer doesn't
> have to make assumptions about indices and it's a bit more explicit
> about which OPP table of the device (a device can have multiple OPP
> tables) corresponds to which ICC path.
>
> Going by your extreme argument, one can also claim that it's not the
> ICC framework's job to make it easy for consumers to figure out the
> source/destination endpoints or give them names and delete the
> interconnect and interconnect-names properties. That's clearly just as
> absurd a claim.
>
>
> -Saravana
>
> > > > > That's not good design nor is it scalable.
> > > > >
> > > > > > >
> > > > > > > 2. Similarly during parts screening in the factory, some of the
> > > > > > > combinations might not have been screened and can't be guaranteed
> > > > > > > to work.
> > > > > >
> > > > > > As above, it's the provider's job to select the final bandwidth
> > > > > > according to its constraint
> > > > >
> > > > > Same reply as above.
> > > > >
> > > > > > >
> > > > > > > 3. Only a certain set of bandwidth levels might make sense to use from
> > > > > > > a power/performance balance given the device using it. For example:
> > > > > > > - The big CPU might not want to use some of the lower bandwidths
> > > > > > > but the little CPU might want to.
> > > > > > > - The big CPU might not want to use some intermediate bandwidth
> > > > > > > points if they don't save a lot of power compared to a higher
> > > > > > > bandwidth levels, but the little CPU might want to.
> > > > > > > - The little CPU might never want to use the higher set of
> > > > > > > bandwidth levels since they won't be power efficient for the use
> > > > > > > cases that might run on it.
> > > > > >
> > > > > > These example are quite vague about the reasons why little might never
> > > > > > want to use higher bandwidth.
> > > > >
> > > > > How is it vague? I just said because of power/performance balance.
> > > > >
> > > > > > But then, if little doesn't ask high bandwidth it will not use them.
> > > > >
> > > > > If you are running a heuristics based algorithm to pick bandwidth,
> > > > > this is how it'll know NOT to use some of the bandwidth levels.
> > > >
> > > > so you want to set a bandwidth according to the cpu frequency which is
> > > > what has been proposed in other thread
> > >
> > > Nope, that's just one heuristic. Often times it's based on hardware
> > > monitors measuring interconnect activity. If you go look at the SDM845
> > > in a Pixel 3, almost nothing is directly tied to the CPU frequency.
> > >
> > > Even if you are scaling bandwidth based on other hardware
> > > measurements, you might want to avoid some bandwidth level provided by
> > > the interconnect providers because it's suboptimal.
> > >
> > > For example, when making bandwidth votes to accommodate the big CPUs,
> > > you might never want to use some of the lower bandwidth levels because
> > > they are not power efficient for any CPU frequency or any bandwidth
> > > level. Because at those levels the memory/interconnect is so slow that
> > > it has a non-trivial utilization increase (because the CPU is
> > > stalling) of the big CPUs.
> > >
> > > Again, this is completely different from what the providers/icc
> > > framework does. Which is, once the request is made, they aggregate and
> > > set the actual interconnect frequencies correctly.
> > >
> > > > >
> > > > > > >
> > > > > > > 4. It might not make sense from a system level power perspective.
> > > > > > > Let's take an example of a path S (source) -> A -> B -> C -> D
> > > > > > > (destination).
> > > > > > > - A supports only 2, 5, 7 and 10 GB/s. B supports 1, 2 ... 10 GB/s.
> > > > > > > C supports 5 and 10 GB/s
> > > > > > > - If you combine and list the superset of bandwidth levels
> > > > > > > supported in that path, that'd be 1, 2, 3, ... 10 GB/s.
> > > > > > > - Which set of bandwidth levels make sense will depend on the
> > > > > > > hardware characteristics of the interconnects.
> > > > > > > - If B is the biggest power sink, then you might want to use all 10
> > > > > > > levels.
> > > > > > > - If A is the biggest power sink, then you might want to use all 2,
> > > > > > > 5 and 10 GB/s of the levels.
> > > > > > > - If C is the biggest power sink then you might only want to use 5
> > > > > > > and 10 GB/s
> > > > > > > - The more hops and paths you get the more convoluted this gets.
> > > > > > >
> > > > > > > 5. The design of the interconnects themselves might have an impact on
> > > > > > > which bandwidth levels are used.
> > > > > > > - For example, the FIFO depth between two specific interconnects
> > > > > > > might affect the valid bandwidth levels for a specific path.
> > > > > > > - Say S1 -> A -> B -> D1, S2 -> C -> B -> D1 and S2 -> C -> D2 are
> > > > > > > three paths.
> > > > > > > - If C <-> B FIFO depth is small, then there might be a requirement
> > > > > > > that C and B be closely performance matched to avoid system level
> > > > > > > congestion due to back pressure.
> > > > > > > - So S2 -> D1 path can't use all the bandwidth levels supported by
> > > > > > > C-B combination.
> > > > > > > - But S2 -> D2 can use all the bandwidth levels supported by C.
> > > > > > > - And S1 -> D1 can use all the levels supported by A-B combination.
> > > > > > >
> > > > > >
> > > > > > All the examples above makes sense but have to be handle by the
> > > > > > provider not the consumer. The consumer asks for a bandwidth according
> > > > > > to its constraints. Then the provider which is the driver that manages
> > > > > > the interconnect IP, should manage all this hardware and platform
> > > > > > specific stuff related to the interconnect IP in order to set the
> > > > > > optimal bandwidth that fit both consumer constraint and platform
> > > > > > specific configuration.
> > > > >
> > > > > Sure, but the provider itself can have interconnect properties to
> > > > > indicate which other interconnects it's tied to. And the provider will
> > > > > still need the interconnect-opp-table to denote which bandwidth levels
> > > > > are sensible to use with each of its connections.
> > >
> > > You seem to have missed this comment.
> > >
> > > Thanks,
> > > Saravana
> > >
> > > > > So in some instances the interconnect-opp-table covers the needs of
> > > > > purely consumers and in some instances purely providers. But in either
> > > > > case, it's still needed to describe the hardware properly.
> > > > >
> > > > > -Saravana
> > > > >
> > > > > > > These are just some of the reasons I could recollect in a few minutes.
> > > > > > > These are all real world cases I had to deal with in the past several
> > > > > > > years of dealing with scaling interconnects. I'm sure vendors and SoCs
> > > > > > > I'm not familiar with have other good reasons I'm not aware of.
> > > > > > >
> > > > > > > Trying to figure this all out by aggregating OPP tables of
> > > > > > > interconnect providers just isn't feasible nor is it efficient. The
> > > > > > > OPP tables for an interconnect path is describing the valid BW levels
> > > > > > > supported by that path and verified in hardware and makes a lot of
> > > > > > > sense to capture it clearly in DT.
> > > > > > >
> > > > > > > > So such kind of OPP table should be at
> > > > > > > > provider level but not at path level.
> > > > > > >
> > > > > > > They can also use it if they want to, but they'll probably want to use
> > > > > > > a frequency OPP table.
> > > > > > >
> > > > > > >
> > > > > > > -Saravana
> > > > > > >
> > > > > > > >
> > > > > > > > >
> > > > > > > > > Signed-off-by: Saravana Kannan <saravanak@google.com>
> > > > > > > > > ---
> > > > > > > > > drivers/interconnect/core.c | 27 ++++++++++++++++++++++++++-
> > > > > > > > > include/linux/interconnect.h | 7 +++++++
> > > > > > > > > 2 files changed, 33 insertions(+), 1 deletion(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
> > > > > > > > > index 871eb4bc4efc..881bac80bc1e 100644
> > > > > > > > > --- a/drivers/interconnect/core.c
> > > > > > > > > +++ b/drivers/interconnect/core.c
> > > > > > > > > @@ -47,6 +47,7 @@ struct icc_req {
> > > > > > > > > */
> > > > > > > > > struct icc_path {
> > > > > > > > > size_t num_nodes;
> > > > > > > > > + struct opp_table *opp_table;
> > > > > > > > > struct icc_req reqs[];
> > > > > > > > > };
> > > > > > > > >
> > > > > > > > > @@ -313,7 +314,7 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
> > > > > > > > > {
> > > > > > > > > struct icc_path *path = ERR_PTR(-EPROBE_DEFER);
> > > > > > > > > struct icc_node *src_node, *dst_node;
> > > > > > > > > - struct device_node *np = NULL;
> > > > > > > > > + struct device_node *np = NULL, *opp_node;
> > > > > > > > > struct of_phandle_args src_args, dst_args;
> > > > > > > > > int idx = 0;
> > > > > > > > > int ret;
> > > > > > > > > @@ -381,10 +382,34 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
> > > > > > > > > dev_err(dev, "%s: invalid path=%ld\n", __func__, PTR_ERR(path));
> > > > > > > > > mutex_unlock(&icc_lock);
> > > > > > > > >
> > > > > > > > > + opp_node = of_parse_phandle(np, "interconnect-opp-table", idx);
> > > > > > > > > + if (opp_node) {
> > > > > > > > > + path->opp_table = dev_pm_opp_of_find_table_from_node(opp_node);
> > > > > > > > > + of_node_put(opp_node);
> > > > > > > > > + }
> > > > > > > > > +
> > > > > > > > > +
> > > > > > > > > return path;
> > > > > > > > > }
> > > > > > > > > EXPORT_SYMBOL_GPL(of_icc_get);
> > > > > > > > >
> > > > > > > > > +/**
> > > > > > > > > + * icc_get_opp_table() - Get the OPP table that corresponds to a path
> > > > > > > > > + * @path: reference to the path returned by icc_get()
> > > > > > > > > + *
> > > > > > > > > + * This function will return the OPP table that corresponds to a path handle.
> > > > > > > > > + * If the interconnect API is disabled, NULL is returned and the consumer
> > > > > > > > > + * drivers will still build. Drivers are free to handle this specifically, but
> > > > > > > > > + * they don't have to.
> > > > > > > > > + *
> > > > > > > > > + * Return: opp_table pointer on success. NULL is returned when the API is
> > > > > > > > > + * disabled or the OPP table is missing.
> > > > > > > > > + */
> > > > > > > > > +struct opp_table *icc_get_opp_table(struct icc_path *path)
> > > > > > > > > +{
> > > > > > > > > + return path->opp_table;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > /**
> > > > > > > > > * icc_set_bw() - set bandwidth constraints on an interconnect path
> > > > > > > > > * @path: reference to the path returned by icc_get()
> > > > > > > > > diff --git a/include/linux/interconnect.h b/include/linux/interconnect.h
> > > > > > > > > index dc25864755ba..0c0bc55f0e89 100644
> > > > > > > > > --- a/include/linux/interconnect.h
> > > > > > > > > +++ b/include/linux/interconnect.h
> > > > > > > > > @@ -9,6 +9,7 @@
> > > > > > > > >
> > > > > > > > > #include <linux/mutex.h>
> > > > > > > > > #include <linux/types.h>
> > > > > > > > > +#include <linux/pm_opp.h>
> > > > > > > > >
> > > > > > > > > /* macros for converting to icc units */
> > > > > > > > > #define Bps_to_icc(x) ((x) / 1000)
> > > > > > > > > @@ -28,6 +29,7 @@ struct device;
> > > > > > > > > struct icc_path *icc_get(struct device *dev, const int src_id,
> > > > > > > > > const int dst_id);
> > > > > > > > > struct icc_path *of_icc_get(struct device *dev, const char *name);
> > > > > > > > > +struct opp_table *icc_get_opp_table(struct icc_path *path);
> > > > > > > > > void icc_put(struct icc_path *path);
> > > > > > > > > int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw);
> > > > > > > > >
> > > > > > > > > @@ -49,6 +51,11 @@ static inline void icc_put(struct icc_path *path)
> > > > > > > > > {
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > +static inline struct opp_table *icc_get_opp_table(struct icc_path *path)
> > > > > > > > > +{
> > > > > > > > > + return NULL;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > static inline int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw)
> > > > > > > > > {
> > > > > > > > > return 0;
> > > > > > > > > --
> > > > > > > > > 2.22.0.410.gd8fdbe21b5-goog
> > > > > > > > >
> > > > > >
> > > > > > --
> > > > > > To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
> > > > > >
^ permalink raw reply
* Re: [Sound-open-firmware] [PATCH v2 3/5] ASoC: SOF: Add DT DSP device support
From: Daniel Baluta @ 2019-07-24 7:04 UTC (permalink / raw)
To: Pierre-Louis Bossart
Cc: Mark Rutland, Aisheng Dong, Peng Fan, Fabio Estevam, Anson Huang,
Devicetree List, Daniel Baluta, S.j. Wang, Marco Felsch,
Linux Kernel Mailing List, Paul Olaru, Rob Herring, dl-linux-imx,
Pengutronix Kernel Team, Leonard Crestez, Shawn Guo,
linux-arm-kernel, sound-open-firmware
In-Reply-To: <d85909d6-c7cb-c64b-dfa9-6cee6c0da2cb@linux.intel.com>
On Tue, Jul 23, 2019 at 6:19 PM Pierre-Louis Bossart
<pierre-louis.bossart@linux.intel.com> wrote:
>
>
> > diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig
> > index 61b97fc55bb2..2aa3a1cdf60c 100644
> > --- a/sound/soc/sof/Kconfig
> > +++ b/sound/soc/sof/Kconfig
> > @@ -36,6 +36,15 @@ config SND_SOC_SOF_ACPI
> > Say Y if you need this option
> > If unsure select "N".
> >
> > +config SND_SOC_SOF_DT
> > + tristate "SOF DT enumeration support"
> > + select SND_SOC_SOF
> > + select SND_SOC_SOF_OPTIONS
> > + help
> > + This adds support for Device Tree enumeration. This option is
> > + required to enable i.MX8 devices.
> > + Say Y if you need this option. If unsure select "N".
> > +
>
> [snip]
>
> > diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig
> > index fff64a9970f0..fa35994a79c4 100644
> > --- a/sound/soc/sof/imx/Kconfig
> > +++ b/sound/soc/sof/imx/Kconfig
> > @@ -12,6 +12,7 @@ if SND_SOC_SOF_IMX_TOPLEVEL
> >
> > config SND_SOC_SOF_IMX8
> > tristate "SOF support for i.MX8"
> > + select SND_SOC_SOF_DT
>
> This looks upside down. You should select SOF_DT first then include the
> NXP stuff.
>
> > help
> > This adds support for Sound Open Firmware for NXP i.MX8 platforms
> > Say Y if you have such a device.
> > diff --git a/sound/soc/sof/sof-dt-dev.c b/sound/soc/sof/sof-dt-dev.c
> > new file mode 100644
> > index 000000000000..31429bbb5c7e
> > --- /dev/null
> > +++ b/sound/soc/sof/sof-dt-dev.c
> > @@ -0,0 +1,159 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> > +//
> > +// Copyright 2019 NXP
> > +//
> > +// Author: Daniel Baluta <daniel.baluta@nxp.com>
> > +//
> > +
> > +#include <linux/firmware.h>
> > +#include <linux/module.h>
> > +#include <linux/pm_runtime.h>
> > +#include <sound/sof.h>
> > +
> > +#include "ops.h"
> > +
> > +extern struct snd_sof_dsp_ops sof_imx8_ops;
> > +
> > +static char *fw_path;
> > +module_param(fw_path, charp, 0444);
> > +MODULE_PARM_DESC(fw_path, "alternate path for SOF firmware.");
> > +
> > +static char *tplg_path;
> > +module_param(tplg_path, charp, 0444);
> > +MODULE_PARM_DESC(tplg_path, "alternate path for SOF topology.");
> > +
> > +/* platform specific devices */
> > +#if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8)
> > +static struct sof_dev_desc sof_dt_imx8qxp_desc = {
> > + .default_fw_path = "imx/sof",
> > + .default_tplg_path = "imx/sof-tplg",
> > + .nocodec_fw_filename = "sof-imx8.ri",
> > + .nocodec_tplg_filename = "sof-imx8-nocodec.tplg",
> > + .ops = &sof_imx8_ops,
> > +};
> > +#endif
> > +
> > +static const struct dev_pm_ops sof_dt_pm = {
> > + SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume)
> > + SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume,
> > + NULL)
> > +};
> > +
> > +static void sof_dt_probe_complete(struct device *dev)
> > +{
> > + /* allow runtime_pm */
> > + pm_runtime_set_autosuspend_delay(dev, SND_SOF_SUSPEND_DELAY_MS);
> > + pm_runtime_use_autosuspend(dev);
> > + pm_runtime_enable(dev);
> > +}
> > +
> > +static int sof_dt_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + const struct sof_dev_desc *desc;
> > + /*TODO: create a generic snd_soc_xxx_mach */
> > + struct snd_soc_acpi_mach *mach;
>
> I wonder if you really need to use the same structures. For Intel we get
> absolutely zero info from the firmware so rely on an ACPI codec ID as a
> key to find information on which firmware and topology to use, and which
> machine driver to load. You could have all this information in a DT blob?
Yes. I see your point. I will still need to make a generic structure for
snd_soc_acpi_mach so that everyone can use sof_nocodec_setup function.
Maybe something like this:
struct snd_soc_mach {
union {
struct snd_soc_acpi_mach acpi_mach;
struct snd_soc_of_mach of_mach;
}
};
and then change the prototype of sof_nocodec_setup.
^ permalink raw reply
* Re: [Sound-open-firmware] [PATCH v2 1/5] ASoC: SOF: imx: Add i.MX8 HW support
From: Daniel Baluta @ 2019-07-24 6:54 UTC (permalink / raw)
To: Pierre-Louis Bossart
Cc: Mark Rutland, Aisheng Dong, Peng Fan, Fabio Estevam, Anson Huang,
Devicetree List, Daniel Baluta, S.j. Wang, Marco Felsch,
Linux Kernel Mailing List, Paul Olaru, Rob Herring, dl-linux-imx,
Pengutronix Kernel Team, Leonard Crestez, Shawn Guo,
linux-arm-kernel, sound-open-firmware
In-Reply-To: <a5d44d96-4d50-ee46-a6bf-3ce108b1994a@linux.intel.com>
On Tue, Jul 23, 2019 at 6:18 PM Pierre-Louis Bossart
<pierre-louis.bossart@linux.intel.com> wrote:
>
>
> > diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile
> > new file mode 100644
> > index 000000000000..c69237971da5
> > --- /dev/null
> > +++ b/sound/soc/sof/imx/Makefile
> > @@ -0,0 +1,7 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> > +
> > +ccflags-y += -DDEBUG
>
> this should be removed or in a separate patch.
All right.
>
>
> > +struct imx8_priv {
> > + struct device *dev;
> > + struct snd_sof_dev *sdev;
> > + struct imx_dsp_ipc *dsp_ipc;
> > + struct imx_sc_ipc *sc_ipc;
>
> maybe a comment to explain what 'sc' stands for?
Sure.
>
> > +};
> > +
> > +static void imx8_get_windows(struct snd_sof_dev *sdev)
> > +{
> > + struct sof_ipc_window_elem *elem;
> > + u32 outbox_offset = 0;
> > + u32 stream_offset = 0;
> > + u32 inbox_offset = 0;
> > + u32 outbox_size = 0;
> > + u32 stream_size = 0;
> > + u32 inbox_size = 0;
> > + int i;
> > +
> > + if (!sdev->info_window) {
> > + dev_err(sdev->dev, "error: have no window info\n");
> > + return;
> > + }
> > +
> > + for (i = 0; i < sdev->info_window->num_windows; i++) {
> > + elem = &sdev->info_window->window[i];
> > +
> > + switch (elem->type) {
> > + case SOF_IPC_REGION_UPBOX:
> > + inbox_offset = elem->offset + MBOX_OFFSET;
> > + inbox_size = elem->size;
> > + snd_sof_debugfs_io_item(sdev,
> > + sdev->bar[SOF_FW_BLK_TYPE_SRAM]
> > + + inbox_offset,
> > + elem->size, "inbox",
> > + SOF_DEBUGFS_ACCESS_D0_ONLY);
> > + break;
> > + case SOF_IPC_REGION_DOWNBOX:
> > + outbox_offset = elem->offset + MBOX_OFFSET;
> > + outbox_size = elem->size;
> > + snd_sof_debugfs_io_item(sdev,
> > + sdev->bar[SOF_FW_BLK_TYPE_SRAM]
> > + + outbox_offset,
> > + elem->size, "outbox",
> > + SOF_DEBUGFS_ACCESS_D0_ONLY);
> > + break;
> > + case SOF_IPC_REGION_TRACE:
> > + snd_sof_debugfs_io_item(sdev,
> > + sdev->bar[SOF_FW_BLK_TYPE_SRAM]
> > + + elem->offset + MBOX_OFFSET,
> > + elem->size, "etrace",
> > + SOF_DEBUGFS_ACCESS_D0_ONLY);
> > + break;
> > + case SOF_IPC_REGION_DEBUG:
> > + snd_sof_debugfs_io_item(sdev,
> > + sdev->bar[SOF_FW_BLK_TYPE_SRAM]
> > + + elem->offset + MBOX_OFFSET,
> > + elem->size, "debug",
> > + SOF_DEBUGFS_ACCESS_D0_ONLY);
> > + break;
> > + case SOF_IPC_REGION_STREAM:
> > + stream_offset = elem->offset + MBOX_OFFSET;
> > + stream_size = elem->size;
> > + snd_sof_debugfs_io_item(sdev,
> > + sdev->bar[SOF_FW_BLK_TYPE_SRAM]
> > + + stream_offset,
> > + elem->size, "stream",
> > + SOF_DEBUGFS_ACCESS_D0_ONLY);
> > + break;
> > + case SOF_IPC_REGION_REGS:
> > + snd_sof_debugfs_io_item(sdev,
> > + sdev->bar[SOF_FW_BLK_TYPE_SRAM]
> > + + elem->offset + MBOX_OFFSET,
> > + elem->size, "regs",
> > + SOF_DEBUGFS_ACCESS_D0_ONLY);
> > + break;
> > + case SOF_IPC_REGION_EXCEPTION:
> > + sdev->dsp_oops_offset = elem->offset + MBOX_OFFSET;
> > + snd_sof_debugfs_io_item(sdev,
> > + sdev->bar[SOF_FW_BLK_TYPE_SRAM]
> > + + elem->offset + MBOX_OFFSET,
> > + elem->size, "exception",
> > + SOF_DEBUGFS_ACCESS_D0_ONLY);
> > + break;
> > + default:
> > + dev_err(sdev->dev, "error: get illegal window info\n");
> > + return;
> > + }
> > + }
> > +
> > + if (outbox_size == 0 || inbox_size == 0) {
> > + dev_err(sdev->dev, "error: get illegal mailbox window\n");
> > + return;
> > + }
> > +
> > + snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size,
> > + outbox_offset, outbox_size);
> > + sdev->stream_box.offset = stream_offset;
> > + sdev->stream_box.size = stream_size;
> > +
> > + dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
> > + inbox_offset, inbox_size);
> > + dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
> > + outbox_offset, outbox_size);
> > + dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
> > + stream_offset, stream_size);
> > +}
>
> This looks 100% similar to Baytrail?
Yes!
>
> > +
> > +/*
> > + * IPC Firmware ready.
> > + */
> > +static int imx8_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
> > +{
> > + struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
> > + u32 offset;
> > + int ret;
> > +
> > + /* mailbox must be on 4k boundary */
> > + offset = MBOX_OFFSET;
> > +
> > + dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n",
> > + msg_id, offset);
> > +
> > + /* no need to re-check version/ABI for subsequent boots */
> > + if (!sdev->first_boot)
> > + return 0;
> > +
> > + /* copy data from the DSP FW ready offset */
> > + sof_block_read(sdev, sdev->mailbox_bar, offset, fw_ready,
> > + sizeof(*fw_ready));
> > + snd_sof_dsp_mailbox_init(sdev, fw_ready->dspbox_offset,
> > + fw_ready->dspbox_size,
> > + fw_ready->hostbox_offset,
> > + fw_ready->hostbox_size);
> > +
> > + /* make sure ABI version is compatible */
> > + ret = snd_sof_ipc_valid(sdev);
> > + if (ret < 0)
> > + return ret;
> > +
> > + /* now check for extended data */
> > + snd_sof_fw_parse_ext_data(sdev, SOF_FW_BLK_TYPE_SRAM, MBOX_OFFSET +
> > + sizeof(struct sof_ipc_fw_ready));
> > +
> > + imx8_get_windows(sdev);
> > +
> > + return 0;
> > +}
>
> That code looks nearly similar to the baytrail one except for the last
> line, we should look into factoring this.
Yes, I got most of my inspiration from intel code.
>
> > +
> > +static void imx8_get_reply(struct snd_sof_dev *sdev)
> > +{
> > + struct snd_sof_ipc_msg *msg = sdev->msg;
> > + struct sof_ipc_reply reply;
> > + unsigned long flags;
> > + int ret = 0;
> > +
> > + if (!msg) {
> > + dev_warn(sdev->dev, "unexpected ipc interrupt\n");
> > + return;
> > + }
> > +
> > + /* get reply */
> > + sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
> > +
> > + spin_lock_irqsave(&sdev->ipc_lock, flags);
> > +
> > + if (reply.error < 0) {
> > + memcpy(msg->reply_data, &reply, sizeof(reply));
> > + ret = reply.error;
> > + } else {
> > + /* reply has correct size? */
> > + if (reply.hdr.size != msg->reply_size) {
> > + dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
> > + msg->reply_size, reply.hdr.size);
> > + ret = -EINVAL;
> > + }
> > +
> > + /* read the message */
> > + if (msg->reply_size > 0)
> > + sof_mailbox_read(sdev, sdev->host_box.offset,
> > + msg->reply_data, msg->reply_size);
> > + }
> > +
> > + msg->reply_error = ret;
> > +
> > + spin_unlock_irqrestore(&sdev->ipc_lock, flags);
>
> I don't see a spin_lock/unlock for the get_reply in the Intel code, is
> this necessary?
Hmm, you are right. I think I've used an older version of the intel code
where there a lock.
>
> > +}
> > +
> > +void imx_dsp_handle_reply(struct imx_dsp_ipc *ipc)
> > +{
> > + struct imx8_priv *priv = imx_dsp_get_data(ipc);
> > +
> > + imx8_get_reply(priv->sdev);
> > + snd_sof_ipc_reply(priv->sdev, 0);
> > +}
> > +
> > +void imx_dsp_handle_request(struct imx_dsp_ipc *ipc)
> > +{
> > + struct imx8_priv *priv = imx_dsp_get_data(ipc);
> > +
> > + snd_sof_ipc_msgs_rx(priv->sdev);
> > +}
> > +
> > +struct imx_dsp_ops dsp_ops = {
> > + .handle_reply = imx_dsp_handle_reply,
> > + .handle_request = imx_dsp_handle_request,
> > +};
> > +
> > +static int imx8_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
> > +{
> > + struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
> > +
> > + sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
> > + msg->msg_size);
> > + imx_dsp_ring_doorbell(priv->dsp_ipc, 0);
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * DSP control.
> > + */
> > +static int imx8_run(struct snd_sof_dev *sdev)
> > +{
> > + int ret;
> > + struct imx8_priv *dsp_priv = (struct imx8_priv *)sdev->private;
> > +
> > + ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
> > + IMX_SC_C_OFS_SEL, 1);
> > + if (ret < 0) {
> > + dev_err(sdev->dev, "Error system address offset source select\n");
> > + return ret;
> > + }
> > +
> > + ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
> > + IMX_SC_C_OFS_AUDIO, 0x80);
> > + if (ret < 0) {
> > + dev_err(sdev->dev, "Error system address offset of AUDIO\n");
> > + return ret;
> > + }
> > +
> > + ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
> > + IMX_SC_C_OFS_PERIPH, 0x5A);
> > + if (ret < 0) {
> > + dev_err(sdev->dev, "Error system address offset of PERIPH %d\n",
> > + ret);
> > + return ret;
> > + }
> > +
> > + ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP,
> > + IMX_SC_C_OFS_IRQ, 0x51);
> > + if (ret < 0) {
> > + dev_err(sdev->dev, "Error system address offset of IRQ\n");
> > + return ret;
> > + }
> > +
> > + imx_sc_pm_cpu_start(dsp_priv->sc_ipc, IMX_SC_R_DSP, true,
> > + RESET_VECTOR_VADDR);
> > +
> > + return 0;
> > +}
> > +
> > +static int imx8_probe(struct snd_sof_dev *sdev)
> > +{
> > + struct imx8_priv *priv;
> > + int i;
> > + struct platform_device *pdev =
> > + container_of(sdev->dev, struct platform_device, dev);
> > + struct platform_device *ipc_dev;
> > + struct resource *mmio;
> > + int num_domains = 0;
> > + u32 base, size;
> > + int ret = 0;
> > + struct device_node *np = pdev->dev.of_node;
> > + struct device_node *res_node;
> > + struct resource res;
>
> nit-pick: can we reorder so that we have all counters last and a nice
> xmas-tree shape.
Ack.
>
> > +
> > + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> > + if (!priv)
> > + return -ENOMEM;
> > +
> > + sdev->private = priv;
> > + priv->dev = sdev->dev;
> > + priv->sdev = sdev;
> > +
> > + ret = imx_scu_get_handle(&priv->sc_ipc);
> > + if (ret) {
> > + dev_err(sdev->dev, "Cannot obtain SCU handle (err = %d)\n",
> > + ret);
> > + return ret;
> > + }
> > +
> > + ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp",
> > + PLATFORM_DEVID_NONE,
> > + pdev, sizeof(*pdev));
> > + if (IS_ERR(ipc_dev)) {
> > + dev_err(sdev->dev, "Failed to register platform device\n");
> > + return PTR_ERR(ipc_dev);
> > + }
> > +
> > + priv->dsp_ipc = dev_get_drvdata(&ipc_dev->dev);
> > + if (!priv->dsp_ipc)
> > + return -EPROBE_DEFER;
> > +
> > + imx_dsp_set_data(priv->dsp_ipc, priv);
> > + priv->dsp_ipc->ops = &dsp_ops;
> > +
> > + num_domains = of_count_phandle_with_args(np, "power-domains",
> > + "#power-domain-cells");
> > + for (i = 0; i < num_domains; i++) {
> > + struct device *pd_dev;
> > + struct device_link *link;
> > +
> > + pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i);
> > + if (IS_ERR(pd_dev))
> > + return PTR_ERR(pd_dev);
> > +
> > + link = device_link_add(&pdev->dev, pd_dev,
> > + DL_FLAG_STATELESS |
> > + DL_FLAG_PM_RUNTIME |
> > + DL_FLAG_RPM_ACTIVE);
> > + if (IS_ERR(link))
> > + return PTR_ERR(link);
>
> Question: is the error flow final? Wondering if we release all the
> resources/memory/devices on errors?
Will check again. It seemed no need for resource freeing.
>
> Also are all the resources device-managed, I don't see a remove()?
Good catch for pm stuff. We mostly didn't care about remove because
drivers are always Y in our distribution.
Thanks Pierre for review, I will let some time for others to have a look and
send a new version.
thanks,
Daniel.
^ permalink raw reply
* Re: [PATCH v2 3/6] pwm: jz4740: Apply configuration atomically
From: Uwe Kleine-König @ 2019-07-24 6:47 UTC (permalink / raw)
To: Paul Cercueil
Cc: Thierry Reding, Rob Herring, Mark Rutland, od, linux-pwm,
devicetree, linux-kernel, kernel
In-Reply-To: <1563914800.1918.0@crapouillou.net>
Hello Paul,
On Tue, Jul 23, 2019 at 04:46:40PM -0400, Paul Cercueil wrote:
> Le lun. 22 juil. 2019 à 15:34, Uwe =?iso-8859-1?q?Kleine-K=F6nig?=
> <u.kleine-koenig@pengutronix.de> a écrit :
> > On Fri, Jun 07, 2019 at 05:44:07PM +0200, Paul Cercueil wrote:
> > > - is_enabled = jz4740_timer_is_enabled(pwm->hwpwm);
> > > - if (is_enabled)
> > > - jz4740_pwm_disable(chip, pwm);
> > > + jz4740_pwm_disable(chip, pwm);
> >
> > I assume this stops the PWM. Does this complete the currently running
> > period? How does the PWM behave then? (Does it still drive the output?
> > If so, on which level?)
>
> Some PWM channels work in one mode "TCU1" and others work in "TCU2". The
> mode in which channels work depends on the version of the SoC.
>
> When stopped, the pins of TCU1 channels will be driven to the inactive
> level (which depends on the polarity). It is unknown whether or not the
> currently running period is completed. We set a bit to configure for
> "abrupt shutdown", so I expect that it's not, but somebody would need
> to hook up a logic analyzer to see what's the exact behaviour with
> and without that bit.
This might be done even without a logic analyzer. Just do something
like:
pwm_apply_state(pwm, { .enabled = 1, .period = 5s })
pwm_apply_state(pwm, { .enabled = 1, .period = 5s, .duty = 5s })
and if that takes less then 5s the period is not completed.
And note that "abrupt shutdown" is a bug.
> TCU2 channels on the other hand will stop in the middle of a period,
> leaving the pin hanging at whatever level it was before the stop.
> That's the rationale behind the trick in commit 6580fd173070 ("pwm:
> jz4740: Force TCU2 channels to return to their init level").
Strange, but ok.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH v5 04/13] media: rc: sunxi: Add RXSTA bits definition
From: Sean Young @ 2019-07-24 5:39 UTC (permalink / raw)
To: Maxime Ripard
Cc: Clément Péron, Mauro Carvalho Chehab, Rob Herring,
Mark Rutland, Chen-Yu Tsai, devicetree, linux-kernel, linux-sunxi,
linux-arm-kernel, linux-media
In-Reply-To: <20190723070440.nfmhbrfykumxayjj@flea>
On Tue, Jul 23, 2019 at 09:04:40AM +0200, Maxime Ripard wrote:
> Hi Sean,
>
> On Tue, Jul 23, 2019 at 07:25:57AM +0100, Sean Young wrote:
> > On Mon, Jul 15, 2019 at 01:12:45PM +0100, Sean Young wrote:
> > > On Sun, Jul 14, 2019 at 04:32:22PM +0200, Cl�ment P�ron wrote:
> > > > Hi Sean,
> > > >
> > > > You acked the whole v3 series but this patch has been introduced in v5
> > > > could you ack this one too?
> > >
> > > Acked-by: Sean Young <sean@mess.org>
> >
> > So who's tree should this series go through? It seems mostly device tree.
> > Alternatively I'm happy to try it get merged via the media tree.
>
> Ideally the media bits should go through the media tree, the DT bits
> will go through arm-soc
>
> So you can apply the patches 1-4, 7 and 10, I'll apply the rest.
>
> Does that work for you?
Works for me, I'll add them to my next pull request to Mauro.
Thanks,
Sean
^ permalink raw reply
* Re: [PATCH v2 5/5] arm64: dts: qcom: sdm845-cheza: remove macro from unit name
From: Amit Kucheria @ 2019-07-24 5:21 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, linux-arm-msm, Bjorn Andersson, Rob Herring,
Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML,
Stephen Boyd, Marc Gonzalez
In-Reply-To: <20190724044906.12007-6-vkoul@kernel.org>
On Wed, Jul 24, 2019 at 10:20 AM Vinod Koul <vkoul@kernel.org> wrote:
>
> Unit address is supposed to be a number, using a macro with hex value is
> not recommended, so add the value in unit name.
>
> arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:966.16-969.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x4d: unit name should not have leading "0x"
> arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:971.16-974.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x4e: unit name should not have leading "0x"
> arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:976.16-979.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x4f: unit name should not have leading "0x"
> arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:981.16-984.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x50: unit name should not have leading "0x"
> arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:986.16-989.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x51: unit name should not have leading "0x"
>
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
> index 1ebbd568dfd7..9b27b8346ba1 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
> @@ -963,27 +963,27 @@ ap_ts_i2c: &i2c14 {
> };
>
> &pm8998_adc {
> - adc-chan@ADC5_AMUX_THM1_100K_PU {
> + adc-chan@4d {
> reg = <ADC5_AMUX_THM1_100K_PU>;
> label = "sdm_temp";
> };
>
> - adc-chan@ADC5_AMUX_THM2_100K_PU {
> + adc-chan@4e {
> reg = <ADC5_AMUX_THM2_100K_PU>;
> label = "quiet_temp";
> };
>
> - adc-chan@ADC5_AMUX_THM3_100K_PU {
> + adc-chan@4f {
> reg = <ADC5_AMUX_THM3_100K_PU>;
> label = "lte_temp_1";
> };
>
> - adc-chan@ADC5_AMUX_THM4_100K_PU {
> + adc-chan@50 {
> reg = <ADC5_AMUX_THM4_100K_PU>;
> label = "lte_temp_2";
> };
>
> - adc-chan@ADC5_AMUX_THM5_100K_PU {
> + adc-chan@51 {
> reg = <ADC5_AMUX_THM5_100K_PU>;
> label = "charger_temp";
> };
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH v2 4/5] arm64: dts: qcom: sdm845: remove macro from unit name
From: Amit Kucheria @ 2019-07-24 5:21 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, linux-arm-msm, Bjorn Andersson, Rob Herring,
Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML,
Stephen Boyd, Marc Gonzalez
In-Reply-To: <20190724044906.12007-5-vkoul@kernel.org>
On Wed, Jul 24, 2019 at 10:20 AM Vinod Koul <vkoul@kernel.org> wrote:
>
> Unit name is supposed to be a number, using a macro with hex value is
> not recommended, so add the value in unit name.
>
> arch/arm64/boot/dts/qcom/pm8998.dtsi:81.18-84.6: Warning (unit_address_format): /soc/spmi@c440000/pmic@0/adc@3100/adc-chan@0x06: unit name should not have leading "0x"
> arch/arm64/boot/dts/qcom/pm8998.dtsi:81.18-84.6: Warning (unit_address_format): /soc/spmi@c440000/pmic@0/adc@3100/adc-chan@0x06: unit name should not have leading 0s
>
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/pm8998.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi
> index 051a52df80f9..dc2ce23cde05 100644
> --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi
> @@ -78,7 +78,7 @@
> #size-cells = <0>;
> #io-channel-cells = <1>;
>
> - adc-chan@ADC5_DIE_TEMP {
> + adc-chan@6 {
> reg = <ADC5_DIE_TEMP>;
> label = "die_temp";
> };
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH v2 3/5] arm64: dts: qcom: sdm845: remove unit name for thermal trip points
From: Amit Kucheria @ 2019-07-24 5:20 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, linux-arm-msm, Bjorn Andersson, Rob Herring,
Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML,
Stephen Boyd, Marc Gonzalez
In-Reply-To: <20190724044906.12007-4-vkoul@kernel.org>
On Wed, Jul 24, 2019 at 10:20 AM Vinod Koul <vkoul@kernel.org> wrote:
>
> The thermal trip points have unit name but no reg property, so we can
> remove them
>
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2824.31-2828.7: Warning (unit_address_vs_reg): /thermal-zones/cpu0-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2830.31-2834.7: Warning (unit_address_vs_reg): /thermal-zones/cpu0-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2868.31-2872.7: Warning (unit_address_vs_reg): /thermal-zones/cpu1-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2874.31-2878.7: Warning (unit_address_vs_reg): /thermal-zones/cpu1-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2912.31-2916.7: Warning (unit_address_vs_reg): /thermal-zones/cpu2-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2918.31-2922.7: Warning (unit_address_vs_reg): /thermal-zones/cpu2-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2956.31-2960.7: Warning (unit_address_vs_reg): /thermal-zones/cpu3-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2962.31-2966.7: Warning (unit_address_vs_reg): /thermal-zones/cpu3-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3000.31-3004.7: Warning (unit_address_vs_reg): /thermal-zones/cpu4-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3006.31-3010.7: Warning (unit_address_vs_reg): /thermal-zones/cpu4-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3044.31-3048.7: Warning (unit_address_vs_reg): /thermal-zones/cpu5-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3050.31-3054.7: Warning (unit_address_vs_reg): /thermal-zones/cpu5-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3088.31-3092.7: Warning (unit_address_vs_reg): /thermal-zones/cpu6-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3094.31-3098.7: Warning (unit_address_vs_reg): /thermal-zones/cpu6-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3132.31-3136.7: Warning (unit_address_vs_reg): /thermal-zones/cpu7-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3138.31-3142.7: Warning (unit_address_vs_reg): /thermal-zones/cpu7-thermal/trips/trip-point@1: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3176.32-3180.7: Warning (unit_address_vs_reg): /thermal-zones/aoss0-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3191.35-3195.7: Warning (unit_address_vs_reg): /thermal-zones/cluster0-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3211.35-3215.7: Warning (unit_address_vs_reg): /thermal-zones/cluster1-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3231.31-3235.7: Warning (unit_address_vs_reg): /thermal-zones/gpu-thermal-top/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3246.31-3250.7: Warning (unit_address_vs_reg): /thermal-zones/gpu-thermal-bottom/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3261.32-3265.7: Warning (unit_address_vs_reg): /thermal-zones/aoss1-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3276.35-3280.7: Warning (unit_address_vs_reg): /thermal-zones/q6-modem-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3291.30-3295.7: Warning (unit_address_vs_reg): /thermal-zones/mem-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3306.31-3310.7: Warning (unit_address_vs_reg): /thermal-zones/wlan-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3321.33-3325.7: Warning (unit_address_vs_reg): /thermal-zones/q6-hvx-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3336.33-3340.7: Warning (unit_address_vs_reg): /thermal-zones/camera-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3351.32-3355.7: Warning (unit_address_vs_reg): /thermal-zones/video-thermal/trips/trip-point@0: node has a unit name, but no reg property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:3366.32-3370.7: Warning (unit_address_vs_reg): /thermal-zones/modem-thermal/trips/trip-point@0: node has a unit name, but no reg property
>
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/sdm845.dtsi | 58 ++++++++++++++--------------
> 1 file changed, 29 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> index 2985df032179..48bd07646eb4 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> @@ -2815,13 +2815,13 @@
> thermal-sensors = <&tsens0 1>;
>
> trips {
> - cpu0_alert0: trip-point@0 {
> + cpu0_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu0_alert1: trip-point@1 {
> + cpu0_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -2859,13 +2859,13 @@
> thermal-sensors = <&tsens0 2>;
>
> trips {
> - cpu1_alert0: trip-point@0 {
> + cpu1_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu1_alert1: trip-point@1 {
> + cpu1_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -2903,13 +2903,13 @@
> thermal-sensors = <&tsens0 3>;
>
> trips {
> - cpu2_alert0: trip-point@0 {
> + cpu2_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu2_alert1: trip-point@1 {
> + cpu2_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -2947,13 +2947,13 @@
> thermal-sensors = <&tsens0 4>;
>
> trips {
> - cpu3_alert0: trip-point@0 {
> + cpu3_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu3_alert1: trip-point@1 {
> + cpu3_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -2991,13 +2991,13 @@
> thermal-sensors = <&tsens0 7>;
>
> trips {
> - cpu4_alert0: trip-point@0 {
> + cpu4_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu4_alert1: trip-point@1 {
> + cpu4_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -3035,13 +3035,13 @@
> thermal-sensors = <&tsens0 8>;
>
> trips {
> - cpu5_alert0: trip-point@0 {
> + cpu5_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu5_alert1: trip-point@1 {
> + cpu5_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -3079,13 +3079,13 @@
> thermal-sensors = <&tsens0 9>;
>
> trips {
> - cpu6_alert0: trip-point@0 {
> + cpu6_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu6_alert1: trip-point@1 {
> + cpu6_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -3123,13 +3123,13 @@
> thermal-sensors = <&tsens0 10>;
>
> trips {
> - cpu7_alert0: trip-point@0 {
> + cpu7_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "passive";
> };
>
> - cpu7_alert1: trip-point@1 {
> + cpu7_alert1: trip-point1 {
> temperature = <95000>;
> hysteresis = <2000>;
> type = "passive";
> @@ -3167,7 +3167,7 @@
> thermal-sensors = <&tsens0 0>;
>
> trips {
> - aoss0_alert0: trip-point@0 {
> + aoss0_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3182,7 +3182,7 @@
> thermal-sensors = <&tsens0 5>;
>
> trips {
> - cluster0_alert0: trip-point@0 {
> + cluster0_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3202,7 +3202,7 @@
> thermal-sensors = <&tsens0 6>;
>
> trips {
> - cluster1_alert0: trip-point@0 {
> + cluster1_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3222,7 +3222,7 @@
> thermal-sensors = <&tsens0 11>;
>
> trips {
> - gpu1_alert0: trip-point@0 {
> + gpu1_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3237,7 +3237,7 @@
> thermal-sensors = <&tsens0 12>;
>
> trips {
> - gpu2_alert0: trip-point@0 {
> + gpu2_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3252,7 +3252,7 @@
> thermal-sensors = <&tsens1 0>;
>
> trips {
> - aoss1_alert0: trip-point@0 {
> + aoss1_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3267,7 +3267,7 @@
> thermal-sensors = <&tsens1 1>;
>
> trips {
> - q6_modem_alert0: trip-point@0 {
> + q6_modem_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3282,7 +3282,7 @@
> thermal-sensors = <&tsens1 2>;
>
> trips {
> - mem_alert0: trip-point@0 {
> + mem_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3297,7 +3297,7 @@
> thermal-sensors = <&tsens1 3>;
>
> trips {
> - wlan_alert0: trip-point@0 {
> + wlan_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3312,7 +3312,7 @@
> thermal-sensors = <&tsens1 4>;
>
> trips {
> - q6_hvx_alert0: trip-point@0 {
> + q6_hvx_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3327,7 +3327,7 @@
> thermal-sensors = <&tsens1 5>;
>
> trips {
> - camera_alert0: trip-point@0 {
> + camera_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3342,7 +3342,7 @@
> thermal-sensors = <&tsens1 6>;
>
> trips {
> - video_alert0: trip-point@0 {
> + video_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> @@ -3357,7 +3357,7 @@
> thermal-sensors = <&tsens1 7>;
>
> trips {
> - modem_alert0: trip-point@0 {
> + modem_alert0: trip-point0 {
> temperature = <90000>;
> hysteresis = <2000>;
> type = "hot";
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH v4 2/3] dt-bindings: rng: add bindings for MediaTek ARMv8 SoCs
From: Neal Liu @ 2019-07-24 5:04 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, devicetree@vger.kernel.org, Herbert Xu,
wsd_upstream, Sean Wang, linux-kernel@vger.kernel.org,
Crystal Guo (郭晶), linux-crypto@vger.kernel.org,
Matt Mackall, Matthias Brugger,
linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <CAL_Jsq+SRhd=-5O2G_CMfJX9Z188kvA05MQOXaU1J8iExwUixQ@mail.gmail.com>
On Tue, 2019-07-23 at 08:35 -0600, Rob Herring wrote:
> On Mon, Jul 22, 2019 at 8:21 PM Neal Liu <neal.liu@mediatek.com> wrote:
> >
>
> Please don't top post to lists.
>
> > Dear Rob,
> > You can check my driver for detail:
> > http://patchwork.kernel.org/patch/11012475/ or patchset 3/3
>
> I could, or you could just answer my question.
>
> >
> > This driver is registered as hardware random number generator, and
> > combines with rng-core.
> > We want to add one rng hw based on the dts. Is this proper or do you
> > have other suggestion to meet this requirement?
>
> It depends. There doesn't appear to be any resource configuration, so
> why does it need to be in DT. DT is not the only way instantiate
> drivers.
>
> Rob
This hwrng is only supported on some chipsets. It needs DT to identify
which platform is supported or not. Is there any better idea to meet
this requirement?
Neal
> >
> > Thanks
> >
> >
> > On Tue, 2019-07-23 at 01:13 +0800, Rob Herring wrote:
> > > On Mon, Jun 24, 2019 at 03:24:11PM +0800, Neal Liu wrote:
> > > > Document the binding used by the MediaTek ARMv8 SoCs random
> > > > number generator with TrustZone enabled.
> > > >
> > > > Signed-off-by: Neal Liu <neal.liu@mediatek.com>
> > > > ---
> > > > .../devicetree/bindings/rng/mtk-sec-rng.txt | 10 ++++++++++
> > > > 1 file changed, 10 insertions(+)
> > > > create mode 100644 Documentation/devicetree/bindings/rng/mtk-sec-rng.txt
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/rng/mtk-sec-rng.txt b/Documentation/devicetree/bindings/rng/mtk-sec-rng.txt
> > > > new file mode 100644
> > > > index 0000000..c04ce15
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/rng/mtk-sec-rng.txt
> > > > @@ -0,0 +1,10 @@
> > > > +MediaTek random number generator with TrustZone enabled
> > > > +
> > > > +Required properties:
> > > > +- compatible : Should be "mediatek,mtk-sec-rng"
> > >
> > > What's the interface to access this?
> > >
> > > A node with a 'compatible' and nothing else is a sign of something that
> > > a parent device should instantiate and doesn't need to be in DT. IOW,
> > > what do complete bindings for firmware functions look like?
> > >
> > > > +
> > > > +Example:
> > > > +
> > > > +hwrng: hwrng {
> > > > + compatible = "mediatek,mtk-sec-rng";
> > > > +}
> > > > --
> > > > 1.7.9.5
> > > >
> > >
> > > _______________________________________________
> > > Linux-mediatek mailing list
> > > Linux-mediatek@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-mediatek
> >
> >
^ permalink raw reply
* Re: [PATCH v2 2/5] arm64: dts: qcom: sdm845: remove unnecessary properties for dsi nodes
From: Amit Kucheria @ 2019-07-24 5:01 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, linux-arm-msm, Bjorn Andersson, Rob Herring,
Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML,
Stephen Boyd, Marc Gonzalez
In-Reply-To: <20190724044906.12007-3-vkoul@kernel.org>
On Wed, Jul 24, 2019 at 10:20 AM Vinod Koul <vkoul@kernel.org> wrote:
>
> We get a warning about unnecessary properties of
>
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2211.22-2257.6: Warning (avoid_unnecessary_addr_size): /soc/mdss@ae00000/dsi@ae94000: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
> arch/arm64/boot/dts/qcom/sdm845.dtsi:2278.22-2324.6: Warning (avoid_unnecessary_addr_size): /soc/mdss@ae00000/dsi@ae96000: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
>
> So, remove these properties
>
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/sdm845.dtsi | 6 ------
> 1 file changed, 6 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> index e81f4a6d08ce..2985df032179 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> @@ -2234,9 +2234,6 @@
>
> status = "disabled";
>
> - #address-cells = <1>;
> - #size-cells = <0>;
> -
> ports {
> #address-cells = <1>;
> #size-cells = <0>;
> @@ -2301,9 +2298,6 @@
>
> status = "disabled";
>
> - #address-cells = <1>;
> - #size-cells = <0>;
> -
> ports {
> #address-cells = <1>;
> #size-cells = <0>;
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH v2 1/5] arm64: dts: qcom: sdm845: Add unit name to soc node
From: Amit Kucheria @ 2019-07-24 5:00 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, linux-arm-msm, Bjorn Andersson, Rob Herring,
Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML,
Stephen Boyd, Marc Gonzalez
In-Reply-To: <20190724044906.12007-2-vkoul@kernel.org>
On Wed, Jul 24, 2019 at 10:20 AM Vinod Koul <vkoul@kernel.org> wrote:
>
> We get a warning about missing unit name for soc node, so add it.
>
> arch/arm64/boot/dts/qcom/sdm845.dtsi:623.11-2814.4: Warning (unit_address_vs_reg): /soc: node has a reg or ranges property, but no unit name
>
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> index 601cfb078bd5..e81f4a6d08ce 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> @@ -620,7 +620,7 @@
> method = "smc";
> };
>
> - soc: soc {
> + soc: soc@0 {
> #address-cells = <2>;
> #size-cells = <2>;
> ranges = <0 0 0 0 0x10 0>;
> --
> 2.20.1
>
^ permalink raw reply
* [PATCH v2 5/5] arm64: dts: qcom: sdm845-cheza: remove macro from unit name
From: Vinod Koul @ 2019-07-24 4:49 UTC (permalink / raw)
To: Andy Gross
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Rob Herring,
Mark Rutland, devicetree, linux-kernel, Stephen Boyd,
Amit Kucheria, Marc Gonzalez
In-Reply-To: <20190724044906.12007-1-vkoul@kernel.org>
Unit address is supposed to be a number, using a macro with hex value is
not recommended, so add the value in unit name.
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:966.16-969.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x4d: unit name should not have leading "0x"
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:971.16-974.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x4e: unit name should not have leading "0x"
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:976.16-979.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x4f: unit name should not have leading "0x"
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:981.16-984.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x50: unit name should not have leading "0x"
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi:986.16-989.4: Warning (unit_address_format): /soc@0/spmi@c440000/pmic@0/adc@3100/adc-chan@0x51: unit name should not have leading "0x"
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
---
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
index 1ebbd568dfd7..9b27b8346ba1 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
@@ -963,27 +963,27 @@ ap_ts_i2c: &i2c14 {
};
&pm8998_adc {
- adc-chan@ADC5_AMUX_THM1_100K_PU {
+ adc-chan@4d {
reg = <ADC5_AMUX_THM1_100K_PU>;
label = "sdm_temp";
};
- adc-chan@ADC5_AMUX_THM2_100K_PU {
+ adc-chan@4e {
reg = <ADC5_AMUX_THM2_100K_PU>;
label = "quiet_temp";
};
- adc-chan@ADC5_AMUX_THM3_100K_PU {
+ adc-chan@4f {
reg = <ADC5_AMUX_THM3_100K_PU>;
label = "lte_temp_1";
};
- adc-chan@ADC5_AMUX_THM4_100K_PU {
+ adc-chan@50 {
reg = <ADC5_AMUX_THM4_100K_PU>;
label = "lte_temp_2";
};
- adc-chan@ADC5_AMUX_THM5_100K_PU {
+ adc-chan@51 {
reg = <ADC5_AMUX_THM5_100K_PU>;
label = "charger_temp";
};
--
2.20.1
^ permalink raw reply related
* [PATCH v2 4/5] arm64: dts: qcom: sdm845: remove macro from unit name
From: Vinod Koul @ 2019-07-24 4:49 UTC (permalink / raw)
To: Andy Gross
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Rob Herring,
Mark Rutland, devicetree, linux-kernel, Stephen Boyd,
Amit Kucheria, Marc Gonzalez
In-Reply-To: <20190724044906.12007-1-vkoul@kernel.org>
Unit name is supposed to be a number, using a macro with hex value is
not recommended, so add the value in unit name.
arch/arm64/boot/dts/qcom/pm8998.dtsi:81.18-84.6: Warning (unit_address_format): /soc/spmi@c440000/pmic@0/adc@3100/adc-chan@0x06: unit name should not have leading "0x"
arch/arm64/boot/dts/qcom/pm8998.dtsi:81.18-84.6: Warning (unit_address_format): /soc/spmi@c440000/pmic@0/adc@3100/adc-chan@0x06: unit name should not have leading 0s
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
arch/arm64/boot/dts/qcom/pm8998.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi
index 051a52df80f9..dc2ce23cde05 100644
--- a/arch/arm64/boot/dts/qcom/pm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi
@@ -78,7 +78,7 @@
#size-cells = <0>;
#io-channel-cells = <1>;
- adc-chan@ADC5_DIE_TEMP {
+ adc-chan@6 {
reg = <ADC5_DIE_TEMP>;
label = "die_temp";
};
--
2.20.1
^ permalink raw reply related
* [PATCH v2 3/5] arm64: dts: qcom: sdm845: remove unit name for thermal trip points
From: Vinod Koul @ 2019-07-24 4:49 UTC (permalink / raw)
To: Andy Gross
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Rob Herring,
Mark Rutland, devicetree, linux-kernel, Stephen Boyd,
Amit Kucheria, Marc Gonzalez
In-Reply-To: <20190724044906.12007-1-vkoul@kernel.org>
The thermal trip points have unit name but no reg property, so we can
remove them
arch/arm64/boot/dts/qcom/sdm845.dtsi:2824.31-2828.7: Warning (unit_address_vs_reg): /thermal-zones/cpu0-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2830.31-2834.7: Warning (unit_address_vs_reg): /thermal-zones/cpu0-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2868.31-2872.7: Warning (unit_address_vs_reg): /thermal-zones/cpu1-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2874.31-2878.7: Warning (unit_address_vs_reg): /thermal-zones/cpu1-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2912.31-2916.7: Warning (unit_address_vs_reg): /thermal-zones/cpu2-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2918.31-2922.7: Warning (unit_address_vs_reg): /thermal-zones/cpu2-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2956.31-2960.7: Warning (unit_address_vs_reg): /thermal-zones/cpu3-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2962.31-2966.7: Warning (unit_address_vs_reg): /thermal-zones/cpu3-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3000.31-3004.7: Warning (unit_address_vs_reg): /thermal-zones/cpu4-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3006.31-3010.7: Warning (unit_address_vs_reg): /thermal-zones/cpu4-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3044.31-3048.7: Warning (unit_address_vs_reg): /thermal-zones/cpu5-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3050.31-3054.7: Warning (unit_address_vs_reg): /thermal-zones/cpu5-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3088.31-3092.7: Warning (unit_address_vs_reg): /thermal-zones/cpu6-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3094.31-3098.7: Warning (unit_address_vs_reg): /thermal-zones/cpu6-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3132.31-3136.7: Warning (unit_address_vs_reg): /thermal-zones/cpu7-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3138.31-3142.7: Warning (unit_address_vs_reg): /thermal-zones/cpu7-thermal/trips/trip-point@1: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3176.32-3180.7: Warning (unit_address_vs_reg): /thermal-zones/aoss0-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3191.35-3195.7: Warning (unit_address_vs_reg): /thermal-zones/cluster0-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3211.35-3215.7: Warning (unit_address_vs_reg): /thermal-zones/cluster1-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3231.31-3235.7: Warning (unit_address_vs_reg): /thermal-zones/gpu-thermal-top/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3246.31-3250.7: Warning (unit_address_vs_reg): /thermal-zones/gpu-thermal-bottom/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3261.32-3265.7: Warning (unit_address_vs_reg): /thermal-zones/aoss1-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3276.35-3280.7: Warning (unit_address_vs_reg): /thermal-zones/q6-modem-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3291.30-3295.7: Warning (unit_address_vs_reg): /thermal-zones/mem-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3306.31-3310.7: Warning (unit_address_vs_reg): /thermal-zones/wlan-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3321.33-3325.7: Warning (unit_address_vs_reg): /thermal-zones/q6-hvx-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3336.33-3340.7: Warning (unit_address_vs_reg): /thermal-zones/camera-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3351.32-3355.7: Warning (unit_address_vs_reg): /thermal-zones/video-thermal/trips/trip-point@0: node has a unit name, but no reg property
arch/arm64/boot/dts/qcom/sdm845.dtsi:3366.32-3370.7: Warning (unit_address_vs_reg): /thermal-zones/modem-thermal/trips/trip-point@0: node has a unit name, but no reg property
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
---
arch/arm64/boot/dts/qcom/sdm845.dtsi | 58 ++++++++++++++--------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 2985df032179..48bd07646eb4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -2815,13 +2815,13 @@
thermal-sensors = <&tsens0 1>;
trips {
- cpu0_alert0: trip-point@0 {
+ cpu0_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu0_alert1: trip-point@1 {
+ cpu0_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -2859,13 +2859,13 @@
thermal-sensors = <&tsens0 2>;
trips {
- cpu1_alert0: trip-point@0 {
+ cpu1_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu1_alert1: trip-point@1 {
+ cpu1_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -2903,13 +2903,13 @@
thermal-sensors = <&tsens0 3>;
trips {
- cpu2_alert0: trip-point@0 {
+ cpu2_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu2_alert1: trip-point@1 {
+ cpu2_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -2947,13 +2947,13 @@
thermal-sensors = <&tsens0 4>;
trips {
- cpu3_alert0: trip-point@0 {
+ cpu3_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu3_alert1: trip-point@1 {
+ cpu3_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -2991,13 +2991,13 @@
thermal-sensors = <&tsens0 7>;
trips {
- cpu4_alert0: trip-point@0 {
+ cpu4_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu4_alert1: trip-point@1 {
+ cpu4_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -3035,13 +3035,13 @@
thermal-sensors = <&tsens0 8>;
trips {
- cpu5_alert0: trip-point@0 {
+ cpu5_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu5_alert1: trip-point@1 {
+ cpu5_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -3079,13 +3079,13 @@
thermal-sensors = <&tsens0 9>;
trips {
- cpu6_alert0: trip-point@0 {
+ cpu6_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu6_alert1: trip-point@1 {
+ cpu6_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -3123,13 +3123,13 @@
thermal-sensors = <&tsens0 10>;
trips {
- cpu7_alert0: trip-point@0 {
+ cpu7_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "passive";
};
- cpu7_alert1: trip-point@1 {
+ cpu7_alert1: trip-point1 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
@@ -3167,7 +3167,7 @@
thermal-sensors = <&tsens0 0>;
trips {
- aoss0_alert0: trip-point@0 {
+ aoss0_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3182,7 +3182,7 @@
thermal-sensors = <&tsens0 5>;
trips {
- cluster0_alert0: trip-point@0 {
+ cluster0_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3202,7 +3202,7 @@
thermal-sensors = <&tsens0 6>;
trips {
- cluster1_alert0: trip-point@0 {
+ cluster1_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3222,7 +3222,7 @@
thermal-sensors = <&tsens0 11>;
trips {
- gpu1_alert0: trip-point@0 {
+ gpu1_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3237,7 +3237,7 @@
thermal-sensors = <&tsens0 12>;
trips {
- gpu2_alert0: trip-point@0 {
+ gpu2_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3252,7 +3252,7 @@
thermal-sensors = <&tsens1 0>;
trips {
- aoss1_alert0: trip-point@0 {
+ aoss1_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3267,7 +3267,7 @@
thermal-sensors = <&tsens1 1>;
trips {
- q6_modem_alert0: trip-point@0 {
+ q6_modem_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3282,7 +3282,7 @@
thermal-sensors = <&tsens1 2>;
trips {
- mem_alert0: trip-point@0 {
+ mem_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3297,7 +3297,7 @@
thermal-sensors = <&tsens1 3>;
trips {
- wlan_alert0: trip-point@0 {
+ wlan_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3312,7 +3312,7 @@
thermal-sensors = <&tsens1 4>;
trips {
- q6_hvx_alert0: trip-point@0 {
+ q6_hvx_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3327,7 +3327,7 @@
thermal-sensors = <&tsens1 5>;
trips {
- camera_alert0: trip-point@0 {
+ camera_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3342,7 +3342,7 @@
thermal-sensors = <&tsens1 6>;
trips {
- video_alert0: trip-point@0 {
+ video_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -3357,7 +3357,7 @@
thermal-sensors = <&tsens1 7>;
trips {
- modem_alert0: trip-point@0 {
+ modem_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
--
2.20.1
^ permalink raw reply related
* [PATCH v2 2/5] arm64: dts: qcom: sdm845: remove unnecessary properties for dsi nodes
From: Vinod Koul @ 2019-07-24 4:49 UTC (permalink / raw)
To: Andy Gross
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Rob Herring,
Mark Rutland, devicetree, linux-kernel, Stephen Boyd,
Amit Kucheria, Marc Gonzalez
In-Reply-To: <20190724044906.12007-1-vkoul@kernel.org>
We get a warning about unnecessary properties of
arch/arm64/boot/dts/qcom/sdm845.dtsi:2211.22-2257.6: Warning (avoid_unnecessary_addr_size): /soc/mdss@ae00000/dsi@ae94000: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
arch/arm64/boot/dts/qcom/sdm845.dtsi:2278.22-2324.6: Warning (avoid_unnecessary_addr_size): /soc/mdss@ae00000/dsi@ae96000: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
So, remove these properties
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
---
arch/arm64/boot/dts/qcom/sdm845.dtsi | 6 ------
1 file changed, 6 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index e81f4a6d08ce..2985df032179 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -2234,9 +2234,6 @@
status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
-
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -2301,9 +2298,6 @@
status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
-
ports {
#address-cells = <1>;
#size-cells = <0>;
--
2.20.1
^ permalink raw reply related
* [PATCH v2 1/5] arm64: dts: qcom: sdm845: Add unit name to soc node
From: Vinod Koul @ 2019-07-24 4:49 UTC (permalink / raw)
To: Andy Gross
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Rob Herring,
Mark Rutland, devicetree, linux-kernel, Stephen Boyd,
Amit Kucheria, Marc Gonzalez
In-Reply-To: <20190724044906.12007-1-vkoul@kernel.org>
We get a warning about missing unit name for soc node, so add it.
arch/arm64/boot/dts/qcom/sdm845.dtsi:623.11-2814.4: Warning (unit_address_vs_reg): /soc: node has a reg or ranges property, but no unit name
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
---
arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 601cfb078bd5..e81f4a6d08ce 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -620,7 +620,7 @@
method = "smc";
};
- soc: soc {
+ soc: soc@0 {
#address-cells = <2>;
#size-cells = <2>;
ranges = <0 0 0 0 0x10 0>;
--
2.20.1
^ permalink raw reply related
* [PATCH v2 0/5] arm64: dts: qcom: sdm845: Fix DTS warnings
From: Vinod Koul @ 2019-07-24 4:49 UTC (permalink / raw)
To: Andy Gross
Cc: linux-arm-msm, Bjorn Andersson, Vinod Koul, Rob Herring,
Mark Rutland, devicetree, linux-kernel, Stephen Boyd,
Amit Kucheria, Marc Gonzalez
So this is an attempt to fix some warns on sdm845 dts. We still have bunch
of warnings to fix after this series (duplicate address and node names
having underscores etc).
Lets get long hanging ones fixed, we can see the warns with W=1 or W=2
Changes since v1:
- Fix space after adc node unit address
- Fix typo in commit log
- Add review tags by Stephen
Vinod Koul (5):
arm64: dts: qcom: sdm845: Add unit name to soc node
arm64: dts: qcom: sdm845: remove unnecessary properties for dsi nodes
arm64: dts: qcom: sdm845: remove unit name for thermal trip points
arm64: dts: qcom: sdm845: remove macro from unit name
arm64: dts: qcom: sdm845-cheza: remove macro from unit name
arch/arm64/boot/dts/qcom/pm8998.dtsi | 2 +-
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 10 ++--
arch/arm64/boot/dts/qcom/sdm845.dtsi | 66 ++++++++++------------
3 files changed, 36 insertions(+), 42 deletions(-)
--
2.20.1
^ permalink raw reply
* Re: [RFC,v3 6/9] media: platform: Add Mediatek ISP P1 V4L2 functions
From: Jungo Lin @ 2019-07-24 4:31 UTC (permalink / raw)
To: Tomasz Figa
Cc: devicetree, Sean Cheng (鄭昇弘),
Frederic Chen (陳俊元),
Rynn Wu (吳育恩), srv_heupstream, Rob Herring,
Ryan Yu (余孟修),
Frankie Chiu (邱文凱), Hans Verkuil, ddavenport,
Sj Huang, moderated list:ARM/Mediatek SoC support,
Laurent Pinchart, Matthias Brugger, Mauro Carvalho Chehab, list
In-Reply-To: <CAAFQd5CXeQv74RtqDxYYLVEpsnFbsm0m-kUBDpY_AFmCBO0PyA@mail.gmail.com>
Hi, Tomasz:
On Tue, 2019-07-23 at 19:21 +0900, Tomasz Figa wrote:
> Hi Jungo,
>
> On Thu, Jul 18, 2019 at 1:39 PM Jungo Lin <jungo.lin@mediatek.com> wrote:
> >
> > Hi, Tomasz:
> >
> > On Wed, 2019-07-10 at 18:54 +0900, Tomasz Figa wrote:
> > > Hi Jungo,
> > >
> > > On Tue, Jun 11, 2019 at 11:53:41AM +0800, Jungo Lin wrote:
> [snip]
> > > > +static void mtk_cam_req_try_isp_queue(struct mtk_cam_dev *cam_dev,
> > > > + struct media_request *new_req)
> > > > +{
> > > > + struct mtk_cam_dev_request *req, *req_safe, *cam_dev_req;
> > > > + struct device *dev = &cam_dev->pdev->dev;
> > > > +
> > > > + dev_dbg(dev, "%s new req:%d", __func__, !new_req);
> > > > +
> > > > + if (!cam_dev->streaming) {
> > > > + cam_dev_req = mtk_cam_req_to_dev_req(new_req);
> > > > + spin_lock(&cam_dev->req_lock);
> > > > + list_add_tail(&cam_dev_req->list, &cam_dev->req_list);
> > > > + spin_unlock(&cam_dev->req_lock);
> > > > + dev_dbg(dev, "%s: stream off, no ISP enqueue\n", __func__);
> > > > + return;
> > > > + }
> > > > +
> > > > + /* Normal enqueue flow */
> > > > + if (new_req) {
> > > > + mtk_isp_req_enqueue(dev, new_req);
> > > > + return;
> > > > + }
> > > > +
> > > > + /* Flush all media requests wehen first stream on */
> > > > + list_for_each_entry_safe(req, req_safe, &cam_dev->req_list, list) {
> > > > + list_del(&req->list);
> > > > + mtk_isp_req_enqueue(dev, &req->req);
> > > > + }
> > > > +}
> > >
> > > This will have to be redone, as per the other suggestions, but generally one
> > > would have a function that tries to queue as much as possible from a list to
> > > the hardware and another function that adds a request to the list and calls
> > > the first function.
> > >
> >
> > We revised this function as below.
> > First to check the en-queue conditions:
> > a. stream on
> > b. The composer buffers in SCP are 3, so we only could has 3 jobs
> > at the same time.
> >
> >
> > Second, try to en-queue the frames in the pending job if possible and
> > move them into running job list if possible.
> >
> > The request has been inserted into pending job in mtk_cam_req_validate
> > which is used to validate media_request.
>
> Thanks for replying to each of the comments, that's very helpful.
> Snipped out the parts that I agreed with.
>
> Please note that req_validate is not supposed to change any driver
> state. It's only supposed to validate the request. req_queue is the
> right callback to insert the request into some internal driver
> bookkeeping structures.
>
Yes, in req_validate function, we don't change any driver state.
Below is the function's implementation.
a. Call vb2_request_validate(req) to verify media request.
b. Update the buffer internal structure buffer.
c. Insert the request into pending_job_list to prepare en-queue.
static int mtk_cam_req_validate(struct media_request *req)
{
struct mtk_cam_dev_request *cam_req = mtk_cam_req_to_dev_req(req);
struct mtk_cam_dev *cam = container_of(req->mdev, struct mtk_cam_dev,
media_dev);
struct media_request_object *req_obj;
unsigned long flags;
int ret;
/* run buffer prepare function to initialize buffer DMA address */
ret = vb2_request_validate(req);
if (ret) {
dev_err(cam->dev, "vb2_request_validate failed:%d\n", ret);
return ret;
}
/* update frame_params */
list_for_each_entry(req_obj, &req->objects, list) {
struct vb2_buffer *vb;
struct mtk_cam_dev_buffer *buf;
if (!vb2_request_object_is_buffer(req_obj))
continue;
vb = container_of(req_obj, struct vb2_buffer, req_obj);
buf = mtk_cam_vb2_buf_to_dev_buf(vb);
cam_req->frame_params.dma_bufs[buf->node_id].iova = buf->daddr;
cam_req->frame_params.dma_bufs[buf->node_id].scp_addr =
buf->scp_addr;
}
atomic_set(&cam_req->buf_count, vb2_request_buffer_cnt(req));
/* add to pending job list */
spin_lock_irqsave(&cam->pending_job_lock, flags);
list_add_tail(&cam_req->list, &cam->pending_job_list);
spin_unlock_irqrestore(&cam->pending_job_lock, flags);
return 0;
}
> >
> > void mtk_cam_dev_req_try_queue(struct mtk_cam_dev *cam_dev)
> > {
> > struct mtk_cam_dev_request *req, *req_prev;
> > struct list_head enqueue_job_list;
> > int buffer_cnt = atomic_read(&cam_dev->running_job_count);
> > unsigned long flags;
> >
> > if (!cam_dev->streaming ||
> > buffer_cnt >= MTK_ISP_MAX_RUNNING_JOBS) {
>
> Do we have a guarantee that cam_dev->running_job_count doesn't
> decrement between the atomic_read() above and this line?
>
Ok, we will use cam->pending_job_lock to protect
cam_dev->running_job_count access. Below is the revised version.
void mtk_cam_dev_req_try_queue(struct mtk_cam_dev *cam)
{
struct mtk_cam_dev_request *req, *req_prev;
unsigned long flags;
if (!cam->streaming) {
dev_dbg(cam->dev, "stream is off\n");
return;
}
spin_lock_irqsave(&cam->pending_job_lock, flags);
if (atomic_read(&cam->running_job_count) >= MTK_ISP_MAX_RUNNING_JOBS) {
dev_dbg(cam->dev, "jobs are full\n");
spin_unlock_irqrestore(&cam->pending_job_lock, flags);
return;
}
list_for_each_entry_safe(req, req_prev, &cam->pending_job_list, list) {
list_del(&req->list);
spin_lock_irqsave(&cam->running_job_lock, flags);
list_add_tail(&req->list, &cam->running_job_list);
mtk_isp_req_enqueue(cam, req);
spin_unlock_irqrestore(&cam->running_job_lock, flags);
if (atomic_inc_return(&cam->running_job_count) >=
MTK_ISP_MAX_RUNNING_JOBS)
break;
}
spin_unlock_irqrestore(&cam->pending_job_lock, flags);
}
> > dev_dbg(cam_dev->dev, "stream off or buffers are full:%d\n",
> > buffer_cnt);
> > return;
> > }
> >
> > INIT_LIST_HEAD(&enqueue_job_list);
> >
> > spin_lock(&cam_dev->pending_job_lock);
> > list_for_each_entry_safe(req, req_prev,
> > &cam_dev->pending_job_list, list) {
> > list_del(&req->list);
> > list_add_tail(&req->list, &enqueue_job_list);
>
> What's the reason to use the second list? Could we just take one job
> from pending_job_list, enqueue it and then iterate again?
>
Yes, we could simply the code block to remove enqueue_job_list.
> > if (atomic_inc_return(&cam_dev->running_job_count) >=
> > MTK_ISP_MAX_RUNNING_JOBS)
> > break;
> > }
> > spin_unlock(&cam_dev->pending_job_lock);
> >
> > list_for_each_entry_safe(req, req_prev,
> > &enqueue_job_list, list) {
> > list_del(&req->list);
> > spin_lock_irqsave(&cam_dev->running_job_lock, flags);
> > list_add_tail(&req->list, &cam_dev->running_job_list);
> > spin_unlock_irqrestore(&cam_dev->running_job_lock, flags);
> >
>
> Do we have a guarantee that another thread doesn't run the same
> function ending up calling mtk_isp_req_enqueue() with another request
> before this one and thus making the order of running_job_list
> incorrect?
>
In the new implementation, we use cam->pending_job_lock to protect this
scenario.
> > mtk_isp_req_enqueue(cam_dev, req);
> > }
> > }
> >
> [snip]
> > > > + stride = DIV_ROUND_UP(stride * pixel_byte, 8);
> > > > +
> > > > + if (pix_fmt == V4L2_PIX_FMT_MTISP_F10)
> > > > + stride = ALIGN(stride, 4);
> > >
> > > Is it expected that only the F10 format needs this alignment?
> > >
> >
> > yes, if the pixel bits of image format is 10, the byte alignment of bpl
> > should be 4. Otherwise, it is 8. We will revise this and add more
> > comments.
>
> That means that the B10 format also needs the extra alignment, as
> opposed to what the original code did, right?
>
Sorry for short code snippet.
This alignment checking is only applied to F10, no B10.
If you like to check the full function, you could check this in this
link[1].
static void cal_image_pix_mp(struct mtk_cam_dev *cam, unsigned int
node_id,
struct v4l2_pix_format_mplane *mp)
{
unsigned int bpl, ppl;
unsigned int pixel_bits = get_pixel_bits(mp->pixelformat);
unsigned int width = mp->width;
if (node_id == MTK_CAM_P1_MAIN_STREAM_OUT) {
/* bayer encoding format & 2 bytes alignment */
bpl = ALIGN(DIV_ROUND_UP(width * pixel_bits, 8), 2);
} else if (node_id == MTK_CAM_P1_PACKED_BIN_OUT) {
/*
* The FULL-G encoding format
* 1 G component per pixel
* 1 R component per 4 pixel
* 1 B component per 4 pixel
* Total 4G/1R/1B in 4 pixel (pixel per line:ppl)
*/
ppl = DIV_ROUND_UP(width * 6, 4);
bpl = DIV_ROUND_UP(ppl * pixel_bits, 8);
/* 4 bytes alignment for 10 bit & others are 8 bytes */
if (pixel_bits == 10)
bpl = ALIGN(bpl, 4);
else
bpl = ALIGN(bpl, 8);
}
[1]
https://crrev.com/c/1712885/2/drivers/media/platform/mtk-isp/isp_50/cam/mtk_cam.c#303
> >
> > /* 4 bytes alignment for 10 bit other are 8 bytes alignment */
> > if (pixel_bits == 10)
> > bpl = ALIGN(bpl, 4);
> > else
> > bpl = ALIGN(bpl, 8);
>
> SGTM, thanks.
>
> [snip]
Thanks for your review.
> > > > +
> > > > +static struct v4l2_subdev *
> > > > +mtk_cam_cio_get_active_sensor(struct mtk_cam_dev *cam_dev)
> > > > +{
> > > > + struct media_device *mdev = cam_dev->seninf->entity.graph_obj.mdev;
> > > > + struct media_entity *entity;
> > > > + struct device *dev = &cam_dev->pdev->dev;
> > > > + struct v4l2_subdev *sensor;
> > >
> > > This variable would be unitialized if there is no streaming sensor. Was
> > > there no compiler warning generated for this?
> > >
> >
> > No, there is no compiler warning.
> > But, we will assign sensor to NULL to avoid unnecessary compiler warning
> > with different compiler options.
> >
>
> Thanks. It would be useful if you could check why the compiler you're
> using doesn't show a warning here. We might be missing other
> uninitialized variables.
>
We will feedback to your project team to check the possible reason about
compiler warning issue.
> [snip]
> > > > +}
> > > > +
> > > > +static int mtk_cam_media_link_setup(struct media_entity *entity,
> > > > + const struct media_pad *local,
> > > > + const struct media_pad *remote, u32 flags)
> > > > +{
> > > > + struct mtk_cam_dev *cam_dev =
> > > > + container_of(entity, struct mtk_cam_dev, subdev.entity);
> > > > + u32 pad = local->index;
> > > > +
> > > > + dev_dbg(&cam_dev->pdev->dev, "%s: %d -> %d flags:0x%x\n",
> > > > + __func__, pad, remote->index, flags);
> > > > +
> > > > + if (pad < MTK_CAM_P1_TOTAL_NODES)
> > >
> > > I assume this check is needed, because the pads with higher indexes are not
> > > video nodes? If so, a comment would be helpful here.
> > >
> >
> > Yes, we will new comment as below.
> >
> > /*
> > * Check video nodes is enabled by link setup.
> > * The pad index of video node should be less than
> > * MTK_CAM_P1_TOTAL_NODES.
> > */
> > if (pad < MTK_CAM_P1_TOTAL_NODES)
> > cam_dev->vdev_nodes[pad].enabled =
> > !!(flags & MEDIA_LNK_FL_ENABLED);
> >
>
> Could we rephrase this a bit. The comment still doesn't explain why
> the index should be less than the constant. Perhaps:
>
> /*
> * The video nodes exposed by the driver have pads indexes
> * from 0 to MTK_CAM_P1_TOTAL_NODES - 1.
> */
>
> [snip]
>
Thanks for your suggestion.
We will update this.
> > > > +
> > > > + dev_dbg(dev, "%s: node:%d fd:%d idx:%d\n",
> > > > + __func__,
> > > > + node->id,
> > > > + buf->vbb.request_fd,
> > > > + buf->vbb.vb2_buf.index);
> > > > +
> > > > + /* For request buffers en-queue, handled in mtk_cam_req_try_queue */
> > > > + if (vb->vb2_queue->uses_requests)
> > > > + return;
> > >
> > > I'd suggest removing non-request support from this driver. Even if we end up
> > > with a need to provide compatibility for non-request mode, then it should be
> > > built on top of the requests mode, so that the driver itself doesn't have to
> > > deal with two modes.
> > >
> >
> > The purpose of non-request function in this driver is needed by
> > our camera middle-ware design. It needs 3A statistics buffers before
> > image buffers en-queue. So we need to en-queue 3A statistics with
> > non-request mode in this driver. After MW got the 3A statistics data, it
> > will en-queue the images, tuning buffer and other meta buffers with
> > request mode. Based on this requirement, do you have any suggestion?
> > For upstream driver, should we only consider request mode?
> >
>
> Where does that requirement come from? Why the timing of queuing of
> the buffers to the driver is important?
>
> [snip]
Basically, this requirement comes from our internal camera
middle-ware/3A hal in user space. Since this is not generic requirement,
we will follow your original suggestion to keep the request mode only
and remove other non-request design in other files. For upstream driver,
it should support request mode only.
> > > > +static int mtk_cam_vb2_start_streaming(struct vb2_queue *vq,
> > > > + unsigned int count)
> > > > +{
> > > > + struct mtk_cam_dev *cam_dev = vb2_get_drv_priv(vq);
> > > > + struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vq);
> > > > + struct device *dev = &cam_dev->pdev->dev;
> > > > + unsigned int node_count = cam_dev->subdev.entity.use_count;
> > > > + int ret;
> > > > +
> > > > + if (!node->enabled) {
> > >
> > > How is this synchronized with mtk_cam_media_link_setup()?
> > >
> >
> > We will follow your suggestion and below is our proposal for this
> > function.
> >
> > 1. Use !cam_dev->pipeline.streaming_count to decide the first node to
> > stream-on.
> > 2.a If yes, do the following steps
> > 2.a-1 Call media_pipeline_start function to prevent the link
> > configuration changes.
> > 2.a-2 Call mtk_cam_dev_init_stream function to calculate how many
> > video nodes are enabled and save it into cam_dev->enabled_node_count.
> > 2.a-3 Initialize ISP P1 HW in mtk_isp_hw_init function since end
> > user has called stream-on API
> > 2.b jump step 3.
> >
> > 3. Use cam_dev->streamed_node_count to track how many video nodes are
> > streamed by user space.
> > 4. Check all enabled video nodes are streamed or not based on
> > cam_dev->streamed_node_count & cam_dev->enabled_node_count.
> > 5. If yes, call s_stream on for P1 sub-device
> >
> > Do you think it is reasonable?
> >
>
> That should work indeed.
>
> [snip]
Ok, thanks for your confirmation.
> > > > +
> > > > + mtk_cam_vb2_return_all_buffers(cam_dev, node, VB2_BUF_STATE_ERROR);
> > >
> > > Shouldn't we stop streaming first, so that the hardware operation is
> > > cancelled and any buffers owned by the hardware are released?
> > >
> >
> > For this function, below is the new code flow.
> >
> > 1. Check the first node to stream off based on
> > cam_dev->streamed_node_count & cam_dev->enabled_node_count.
> > 2. If yes, call all s_stream off for P1 sub-device
> > 3. Call mtk_cam_vb2_return_all_buffers for each node
> > 4. Check the last node to stream off
> > 5. If yes, call media_pipeline_stop to allow user space
> > to perform link configuration changes, such as disable link.
> >
> > But, for step 5, is it too late for end user to disable link?
> > For example, for first node, it has called stream off but
> > can't call disable link until the last node is stream off?
> >
>
> I think that should be okay. From the userspace point of view, having
> one of the video nodes streaming implies that the related subdevice
> could be streaming as well. The links between the video nodes and the
> subdevices don't have the DYNAMIC flag, so the userspace should expect
> that it can't change any links connecting to the subdevice when the
> subdevice could be streaming.
>
Ok, got your point. We will keep this design.
> [snip]
> > > > +static void mtk_cam_vb2_buf_request_complete(struct vb2_buffer *vb)
> > > > +{
> > > > + struct mtk_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
> > > > +
> > > > + v4l2_ctrl_request_complete(vb->req_obj.req,
> > > > + dev->v4l2_dev.ctrl_handler);
> > >
> > > This would end up being called multiple times, once for each video node.
> > > Instead, this should be called explicitly by the driver when it completed
> > > the request - perhaps in the frame completion handler?
> > >
> > > With that, we probably wouldn't even need this callback.
> > >
> >
> > First, if we don't implement this callback function, we will receive
> > kernel warning as below.
> >
> > https://elixir.bootlin.com/linux/latest/source/drivers/media/common/videobuf2/videobuf2-v4l2.c#L420
> >
> > Second, this function is only be called in __vb2_queue_cancel function.
> > Moreover, we will remove cam_dev->v4l2_dev.ctrl_handler in next patch.
> > So could we just implement dummy empty function?
> >
> > * @buf_request_complete: a buffer that was never queued to the driver
> > but is
> > * associated with a queued request was canceled.
> > * The driver will have to mark associated objects in the
> > * request as completed; required if requests are
> > * supported.
> >
>
> Good catch, thanks.
>
> Sounds like we may indeed need to implement this callback. In
> particular, we may need to remove the request that the buffer was
> associated with from the driver queue and return the other buffers
> associated to it with an error state. This should be similar to
> handling a request failure.
> [snip]
Before calling this callback function, the VB2's stop_streaming has been
called. Normally, we will return the buffers belonged to this vb2 queu
with error state. On other hand, only if the state of request is
MEDIA_REQUEST_STATE_QUEUED, the buf_request_complete will be called in
__vb2_queue_cancel function. It hints this media request has been
validated and inserted into our driver's pending_job_list or
running_job_list. So we will call mtk_cam_dev_req_cleanup() remove these
requests from driver's list when streaming is off. Since we have no
v4l2_ctrl, do we need to do the above things which is already handled in
mtk_cam_vb2_stop_streaming function? Maybe is this callback function
only designed for v4l2_ctrl_request_complete usage?
static void mtk_cam_dev_req_cleanup(struct mtk_cam_dev *cam)
{
struct mtk_cam_dev_request *req, *req_prev;
unsigned long flags;
dev_dbg(cam->dev, "%s\n", __func__);
spin_lock_irqsave(&cam->pending_job_lock, flags);
list_for_each_entry_safe(req, req_prev, &cam->pending_job_list, list)
list_del(&req->list);
spin_unlock_irqrestore(&cam->pending_job_lock, flags);
spin_lock_irqsave(&cam->running_job_lock, flags);
list_for_each_entry_safe(req, req_prev, &cam->running_job_list, list)
list_del(&req->list);
spin_unlock_irqrestore(&cam->running_job_lock, flags);
}
static void mtk_cam_vb2_stop_streaming(struct vb2_queue *vq)
{
struct mtk_cam_dev *cam = vb2_get_drv_priv(vq);
struct mtk_cam_video_device *node = mtk_cam_vbq_to_vdev(vq);
struct device *dev = cam->dev;
dev_dbg(dev, "%s node:%d count info:%d", __func__,
node->id, atomic_read(&cam->stream_count));
mutex_lock(&cam->op_lock);
if (atomic_read(&cam->stream_count) == cam->enabled_count)
if (v4l2_subdev_call(&cam->subdev, video, s_stream, 0))
dev_err(dev, "failed to stop streaming\n");
mtk_cam_vb2_return_all_buffers(cam, node, VB2_BUF_STATE_ERROR);
/* Check the first node to stream-off */
if (!atomic_dec_and_test(&cam->stream_count)) {
mutex_unlock(&cam->op_lock);
return;
}
mutex_unlock(&cam->op_lock);
mtk_cam_dev_req_cleanup(cam);
media_pipeline_stop(&node->vdev.entity);
}
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static int mtk_cam_vidioc_enum_fmt(struct file *file, void *fh,
> > > > + struct v4l2_fmtdesc *f)
> > > > +{
> > > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file);
> > > > +
> > > > + if (f->index >= node->desc.num_fmts)
> > > > + return -EINVAL;
> > > > +
> > > > + f->pixelformat = node->desc.fmts[f->index].fmt.pix_mp.pixelformat;
> > >
> > > Is the set of formats available always the same regardless of the sensor
> > > format?
> > >
> >
> > Yes, ISP P1 HW output formats are always available without impact
> > by sensor formats.
> >
> > > > + f->flags = 0;
> > >
> > > We need f->description too.
> > >
> >
> > For this description, do you suggest 1). we fill this field in this
> > function or 2). v4l_fill_fmtdesc function in v4l2-ioctl?
> >
> > https://elixir.bootlin.com/linux/latest/source/drivers/media/v4l2-core/v4l2-ioctl.c#L1152
> >
> > Basically, we prefer method 1.
> >
>
> That should be v4l_fill_fmtdesc(), as it already includes other
> vendor-specific formats.
>
> [snip]
Ok, got it. We will follow your suggestion.
> > > > +
> > > > + dev_dbg(&cam_dev->pdev->dev, "%s: fmt:%c%c%c%c, w*h:%u*%u\n",
> > > > + __func__,
> > > > + (in_fmt->fmt.pix_mp.pixelformat & 0xFF),
> > > > + (in_fmt->fmt.pix_mp.pixelformat >> 8) & 0xFF,
> > > > + (in_fmt->fmt.pix_mp.pixelformat >> 16) & 0xFF,
> > > > + (in_fmt->fmt.pix_mp.pixelformat >> 24) & 0xFF,
> > > > + in_fmt->fmt.pix_mp.width, in_fmt->fmt.pix_mp.height);
> > > > +
> > > > + width = in_fmt->fmt.pix_mp.width;
> > > > + height = in_fmt->fmt.pix_mp.height;
> > > > +
> > > > + dev_fmt = mtk_cam_dev_find_fmt(&node->desc,
> > > > + in_fmt->fmt.pix_mp.pixelformat);
> > > > + if (dev_fmt) {
> > > > + mtk_cam_dev_set_img_fmt(&cam_dev->pdev->dev,
> > > > + &in_fmt->fmt.pix_mp,
> > > > + &dev_fmt->fmt.pix_mp,
> > > > + node->id);
> > > > + } else {
> > > > + mtk_cam_dev_load_default_fmt(&cam_dev->pdev->dev,
> > > > + &node->desc, in_fmt);
> > >
> > > We shouldn't just load a default format. This function should validate all
> > > the fields one by one and adjust them to something appropriate.
> > >
> >
> > For ISP P1 HW, we only cares these fields of v4l2_pix_format_mplane.
> > a. width
> > b. height
> > c. pixelformat
> > d. plane_fmt
> > - sizeimage
> > - bytesperline
> > e. num_planes
> > Other fields are consider constant.
> >
> > So if the user space passes one pixel format with un-supported, we will
> > apply the default format firstly and adjust width, height, sizeimage,
> > and bytesperline. We will focus on validate width & height.
> > Is it ok?
>
> I'm not sure I understand your proposal, but let me describe the
> proper behavior here:
>
> if (pixelformat is invalid)
> pixelformat = some valid pixel format;
>
> width = clamp(width, driver min, driver max);
> height = clamp(height, driver min, driver max);
>
> num_planes = 1;
>
> calculate_sizeimage_and_bytesperline(fmt);
>
> fill_in_the_remaining_constant_fields(fmt);
>
> Does it make sense?
>
> [snip]
Yes, here is our new version.
static int mtk_cam_vidioc_try_fmt(struct file *file, void *fh,
struct v4l2_format *f)
{
struct mtk_cam_dev *cam = video_drvdata(file);
struct mtk_cam_video_device *node = file_to_mtk_cam_node(file);
struct device *dev = cam->dev;
const struct v4l2_format *dev_fmt;
struct v4l2_format try_fmt;
dev_dbg(dev, "%s: fmt:%c%c%c%c, w*h:%u*%u\n",
__func__,
(f->fmt.pix_mp.pixelformat & 0xFF),
(f->fmt.pix_mp.pixelformat >> 8) & 0xFF,
(f->fmt.pix_mp.pixelformat >> 16) & 0xFF,
(f->fmt.pix_mp.pixelformat >> 24) & 0xFF,
f->fmt.pix_mp.width, f->fmt.pix_mp.height);
memset(&try_fmt, 0, sizeof(try_fmt));
try_fmt.type = f->type;
/* Validate pixelformat */
dev_fmt = mtk_cam_dev_find_fmt(&node->desc, f->fmt.pix_mp.pixelformat);
if (!dev_fmt) {
dev_dbg(dev, "unknown fmt:%d\n", f->fmt.pix_mp.pixelformat);
dev_fmt = &node->desc.fmts[node->desc.default_fmt_idx];
}
try_fmt.fmt.pix_mp.pixelformat = dev_fmt->fmt.pix_mp.pixelformat;
/* Validate image width & height range */
try_fmt.fmt.pix_mp.width = clamp_val(f->fmt.pix_mp.width,
IMG_MIN_WIDTH, IMG_MAX_WIDTH);
try_fmt.fmt.pix_mp.height = clamp_val(f->fmt.pix_mp.height,
IMG_MIN_HEIGHT, IMG_MAX_HEIGHT);
/* 4 bytes alignment for width */
try_fmt.fmt.pix_mp.width = ALIGN(try_fmt.fmt.pix_mp.width, 4);
/* bytesperline & sizeimage calculation */
cal_image_pix_mp(cam, node->id, &try_fmt.fmt.pix_mp);
/* Constant format fields */
try_fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
try_fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
try_fmt.fmt.pix_mp.num_planes = 1;
try_fmt.fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
try_fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
try_fmt.fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
*f = try_fmt;
return 0;
}
> > > > +static int mtk_cam_vidioc_s_fmt(struct file *file, void *fh,
> > > > + struct v4l2_format *f)
> > > > +{
> > > > + struct mtk_cam_dev *cam_dev = video_drvdata(file);
> > > > + struct mtk_cam_video_device *node = file_to_mtk_cam_node(file);
> > > > +
> > > > + if (cam_dev->streaming)
> > > > + return -EBUSY;
> > >
> > > I think this should rather be something like vb2_queue_is_busy(), which
> > > would prevent format changes if buffers are allocated.
> > >
> >
> > Since vb2_queue_is_busy is static function, would we paste its
> > implementation in this function to check like this?
> >
> > if (node->vdev.queue->owner &&
> > node->vdev.queue->owner != file->private_data) {
> > dev_err(cam_dev->dev, "%s err: buffer allocated\n", __func__);
> > return -EBUSY;
> > }
> >
>
> Sorry, I mixed up the function name. That should've been vb2_is_busy().
>
> [snip]
Got it. Thanks for your suggestion.
> > > > + /* Total pad numbers is video devices + one seninf pad */
> > > > + unsigned int num_subdev_pads = MTK_CAM_CIO_PAD_SINK + 1;
> > > > + unsigned int i;
> > > > + int ret;
> > > > +
> > > > + ret = mtk_cam_media_register(dev,
> > > > + &cam_dev->media_dev);
> > > > + if (ret) {
> > > > + dev_err(dev, "failed to register media device:%d\n", ret);
> > > > + return ret;
> > > > + }
> > > > + dev_info(dev, "Register media device: %s, 0x%pK",
> > > > + MTK_CAM_DEV_P1_NAME, cam_dev->media_dev);
> > >
> > > An info message should be useful to the user in some way. Printing kernel
> > > pointers isn't useful. Something like "registered media0" could be useful to
> > > let the user know which media device is associated with this driver if there
> > > is more than one in the system.
> > >
> >
> > Here is the new log info.
> >
> > dev_info(dev, "media%d register",cam->media_dev.devnode->minor);
> >
>
> Let's fix the missing space and making a bit more readable:
>
> dev_info(dev, "Registered media%d", cam->media_dev.devnode->minor);
>
Ok, we will apply this change.
> >
> > > > +
> > > > + /* Set up v4l2 device */
> > > > + cam_dev->v4l2_dev.mdev = &cam_dev->media_dev;
> > > > + ret = v4l2_device_register(dev, &cam_dev->v4l2_dev);
> > > > + if (ret) {
> > > > + dev_err(dev, "failed to register V4L2 device:%d\n", ret);
> > > > + goto fail_v4l2_dev;
> > >
> > > Please call the labels after the cleanup step that needs to be done. It
> > > makes it easier to spot any ordering errors.
> > >
> >
> > Will fix in next patch.
> >
> > > > + }
> > > > + dev_info(dev, "Register v4l2 device: 0x%pK", cam_dev->v4l2_dev);
> > >
> > > Same as above.
> > >
> >
> > Ditto.
> >
> > dev_info(dev, "Register v4l2 device: %s", cam->v4l2_dev.name);
> >
>
> Perhaps just "Registered %s" to be consistent with the above media log?
>
> [snip]
Ditto.
> > > > +
> > > > +static int mtk_cam_dev_notifier_bound(struct v4l2_async_notifier *notifier,
> > > > + struct v4l2_subdev *sd,
> > > > + struct v4l2_async_subdev *asd)
> > > > +{
> > > > + struct mtk_cam_dev *cam_dev =
> > > > + container_of(notifier, struct mtk_cam_dev, notifier);
> > > > +
> > >
> > > Should we somehow check that the entity we got is seninf indeed and there
> > > was no mistake in DT?
> > >
> >
> > How about to check the entity function of seninf device?
> >
> > if (!(sd->entity.function & MEDIA_ENT_F_VID_IF_BRIDGE)) {
> > dev_dbg(cam->dev, "No MEDIA_ENT_F_VID_IF_BRIDGE function\n");
> > return -ENODEV;
> > }
> >
> > If we need to check DT, may we need to implement this in parse_endpoint
> > callback function of v4l2_async_notifier_parse_fwnode_endpoints?
> >
>
> Yes, checking the entity function is indeed the right way to do this.
>
> [snip]
Thanks for your confirm.
> > > > + .default_fmt_idx = 4,
> > > > + .max_buf_count = 10,
> > >
> > > Where does this number come from?
> > >
> >
> > The default maximum VB2 buffer count is 32.
> > In order to limit memory usage, we like to limit the maximum buffer
> > counts in the driver layer. The maximum buffer count is estimated
> > according to our camera MW.
> >
> > #define VB2_MAX_FRAME (32)
> >
>
> Okay, thanks.
>
> [snip]
> > > > + struct media_pad vdev_pad;
> > > > + struct vb2_queue vbq;
> > > > + struct v4l2_ctrl_handler ctrl_handler;
> > > > + struct list_head pending_list;
> > > > + /* Used for vbq & vdev */
> > >
> > > It's already documented in the kerneldoc comment.
> > >
> >
> > Fixed in next patch.
> > Btw, if we remove this, we will got complain from checkpatch.pl script.
> >
>
> Oh really, that's weird. Okay, please keep it then, sorry for the confusion.
>
> Best regards,
> Tomasz
Ok, thanks for your understanding.
We will rollback this change to avoid checkpatch's complains.
Best regards,
Jungo
^ permalink raw reply
* Re: [PATCH 1/5] arm64: dts: qcom: sdm845: Add unit name to soc node
From: Vinod Koul @ 2019-07-24 4:07 UTC (permalink / raw)
To: Stephen Boyd
Cc: Andy Gross, linux-arm-msm, Bjorn Andersson, Rob Herring,
Mark Rutland, devicetree, linux-kernel
In-Reply-To: <5d371e9d.1c69fb81.8d9f4.1ac0@mx.google.com>
On 23-07-19, 07:50, Stephen Boyd wrote:
> Quoting Vinod Koul (2019-07-22 05:34:18)
> > We get a warning about missing unit name for soc node, so add it.
> >
> > arch/arm64/boot/dts/qcom/sdm845.dtsi:623.11-2814.4: Warning (unit_address_vs_reg): /soc: node has a reg or ranges property, but no unit name
> >
> > Signed-off-by: Vinod Koul <vkoul@kernel.org>
> > ---
>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Thanks for the review
>
> > diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> > index 601cfb078bd5..e81f4a6d08ce 100644
> > --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> > @@ -620,7 +620,7 @@
> > method = "smc";
> > };
> >
> > - soc: soc {
> > + soc: soc@0 {
>
> This is kinda sad, but ok. Maybe you can apply this fix to at least all
> the qcom boards then.
Yeah that is the idea, start with sdm845 and 'reduce' the warns on all
qcom dts files
--
~Vinod
^ permalink raw reply
* RE: [PATCH V15 1/5] dt-bindings: fsl: scu: add thermal binding
From: Anson Huang @ 2019-07-24 3:16 UTC (permalink / raw)
To: Anson Huang, robh+dt@kernel.org, mark.rutland@arm.com,
corbet@lwn.net, shawnguo@kernel.org, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com,
catalin.marinas@arm.com, will.deacon@arm.com, rui.zhang@intel.com,
edubezval@gmail.com, daniel.lezcano@linaro.org, Aisheng Dong,
ulf.hansson@linaro.org, Peng Fan, mchehab+samsung@kernel.org,
linux@roeck-us.net, Daniel Baluta, maxime.ripard@bootlin.com,
horms+renesas@verge.net.au, olof@lixom.net,
jagan@amarulasolutions.com, bjorn.andersson@linaro.org,
Leonard Crestez, dinguyen@kernel.org,
enric.balletbo@collabora.com, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org
Cc: dl-linux-imx
In-Reply-To: <DB3PR0402MB39162C5B5AF828B127DD871EF5E00@DB3PR0402MB3916.eurprd04.prod.outlook.com>
Ping...
> Hi, Daniel/Rui/Eduardo
> Could you please take a look at this patch series?
>
> Anson
>
> > From: Anson Huang <Anson.Huang@nxp.com>
> >
> > NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as system
> > controller, the system controller is in charge of system power, clock
> > and thermal sensors etc. management, Linux kernel has to communicate
> > with system controller via MU (message unit) IPC to get temperature
> > from thermal sensors, this patch adds binding doc for i.MX system
> > controller thermal driver.
> >
> > Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
> > ---
> > No change.
> > ---
> > .../devicetree/bindings/arm/freescale/fsl,scu.txt | 16
> ++++++++++++++++
> > 1 file changed, 16 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > index a575e42..fc3844e 100644
> > --- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > @@ -155,6 +155,17 @@ Required properties:
> > Optional properties:
> > - timeout-sec: contains the watchdog timeout in seconds.
> >
> > +Thermal bindings based on SCU Message Protocol
> > +------------------------------------------------------------
> > +
> > +Required properties:
> > +- compatible: Should be :
> > + "fsl,imx8qxp-sc-thermal"
> > + followed by "fsl,imx-sc-thermal";
> > +
> > +- #thermal-sensor-cells: See
> > Documentation/devicetree/bindings/thermal/thermal.txt
> > + for a description.
> > +
> > Example (imx8qxp):
> > -------------
> > aliases {
> > @@ -222,6 +233,11 @@ firmware {
> > compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
> > timeout-sec = <60>;
> > };
> > +
> > + tsens: thermal-sensor {
> > + compatible = "fsl,imx8qxp-sc-thermal", "fsl,imx-sc-
> > thermal";
> > + #thermal-sensor-cells = <1>;
> > + };
> > };
> > };
> >
> > --
> > 2.7.4
^ permalink raw reply
* Re: [PATCH 2/2] media: i2c: dw9768: Add DW9768 VCM driver
From: Bingbu Cao @ 2019-07-24 3:16 UTC (permalink / raw)
To: dongchun.zhu, mchehab, robh+dt, mark.rutland, matthias.bgg,
sakari.ailus, tfiga, bingbu.cao
Cc: devicetree, srv_heupstream, shengnan.wang, sj.huang,
linux-mediatek, louis.kuo, linux-arm-kernel, linux-media
In-Reply-To: <20190708100641.2702-3-dongchun.zhu@mediatek.com>
On 7/8/19 6:06 PM, dongchun.zhu@mediatek.com wrote:
> From: Dongchun Zhu <dongchun.zhu@mediatek.com>
>
> This patch adds a V4L2 sub-device driver for DW9768 lens voice coil,
> and provides control to set the desired focus.
>
> The DW9807 is a 10 bit DAC from Dongwoon, designed for linear
> control of voice coil motor.
>
> Signed-off-by: Dongchun Zhu <dongchun.zhu@mediatek.com>
> ---
> MAINTAINERS | 1 +
> drivers/media/i2c/Kconfig | 10 +
> drivers/media/i2c/Makefile | 1 +
> drivers/media/i2c/dw9768.c | 458 +++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 470 insertions(+)
> create mode 100644 drivers/media/i2c/dw9768.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8f6ac93..17152d7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4877,6 +4877,7 @@ M: Dongchun Zhu <dongchun.zhu@mediatek.com>
> L: linux-media@vger.kernel.org
> T: git git://linuxtv.org/media_tree.git
> S: Maintained
> +F: drivers/media/i2c/dw9768.c
> F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.txt
>
> DONGWOON DW9807 LENS VOICE COIL DRIVER
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 7793358..8ff6c95 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -1014,6 +1014,16 @@ config VIDEO_DW9714
> capability. This is designed for linear control of
> voice coil motors, controlled via I2C serial interface.
>
> +config VIDEO_DW9768
> + tristate "DW9768 lens voice coil support"
> + depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
> + depends on VIDEO_V4L2_SUBDEV_API
> + help
> + This is a driver for the DW9768 camera lens voice coil.
> + DW9768 is a 10 bit DAC with 100mA output current sink
> + capability. This is designed for linear control of
> + voice coil motors, controlled via I2C serial interface.
> +
> config VIDEO_DW9807_VCM
> tristate "DW9807 lens voice coil support"
> depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index d8ad9da..944fbf6 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -24,6 +24,7 @@ obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
> obj-$(CONFIG_VIDEO_AD5820) += ad5820.o
> obj-$(CONFIG_VIDEO_AK7375) += ak7375.o
> obj-$(CONFIG_VIDEO_DW9714) += dw9714.o
> +obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
> obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
> obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
> obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
> diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
> new file mode 100644
> index 0000000..f5b5591
> --- /dev/null
> +++ b/drivers/media/i2c/dw9768.c
> @@ -0,0 +1,458 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2018 MediaTek Inc.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/pm_runtime.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-subdev.h>
> +
> +#define DW9768_VOLTAGE_ANALOG 2800000
> +#define DW9768_NAME "dw9768"
> +#define DW9768_MAX_FOCUS_POS 1023
> +/*
> + * This sets the minimum granularity for the focus positions.
> + * A value of 1 gives maximum accuracy for a desired focus position
> + */
> +#define DW9768_FOCUS_STEPS 1
> +
> +#define DW9768_CTRL_DELAY_US 5000
> +
> +#define DW9768_REG_DAC_MSB 0x03
> +#define DW9768_REG_DAC_LSB 0x04
> +#define DW9768_REG_NULL 0xff
> +
> +#define DW9768_DAC_SHIFT 8
> +
> +#define DW9768_REG_VALUE_16BIT 2
> +
> +/* dw9768 device structure */
> +struct dw9768_device {
> + struct v4l2_ctrl_handler ctrls;
> + struct v4l2_subdev sd;
> + struct regulator *analog_regulator;
> + /*
> + * Serialize control access, get/set format, get selection
> + * and start streaming.
> + */
> + struct mutex power_lock;
> +
> + int power_count;
> + bool standby;
> +};
> +
> +static inline struct dw9768_device *to_dw9768_vcm(struct v4l2_ctrl *ctrl)
> +{
> + return container_of(ctrl->handler, struct dw9768_device, ctrls);
> +}
> +
> +static inline struct dw9768_device *sd_to_dw9768_vcm(struct v4l2_subdev *subdev)
> +{
> + return container_of(subdev, struct dw9768_device, sd);
> +}
> +
> +static int dw9768_i2c_write(struct dw9768_device *dw9768_dev, u8 *data,
> + int size)
> +{
> + struct i2c_client *client = v4l2_get_subdevdata(&dw9768_dev->sd);
> + struct i2c_msg msg;
> + u8 *w_buf = NULL;
> + u8 retry_cnt = 3;
> + int ret;
> +
> + if (!client->adapter)
> + return -ENODEV;
> +
> + if (size != 1 && size != 2)
> + return -EINVAL;
> +
> + memset(&msg, 0, sizeof(struct i2c_msg));
> +
> + w_buf = kzalloc(size, GFP_KERNEL);
> + if (!w_buf)
> + return -1;
return -ENOMEM;
> +
> + memcpy(w_buf, data, size);
> +
> + msg.addr = client->addr;
> + msg.flags = 0;
> + msg.len = size;
> + msg.buf = w_buf;
> +
> + do {
> + ret = i2c_transfer(client->adapter, &msg, 1);
> + if (ret != 1)
> + dev_err(&client->dev, "write fail, ret:%d, retry:%d\n",
> + ret, retry_cnt);
> + else
> + break;
> + retry_cnt--;
> + } while (retry_cnt != 0);
> +
> + if (retry_cnt == 0) {
> + dev_err(&client->dev, "i2c write fail(%d)\n", ret);
> + return -EIO;
> + }
> +
> + kfree(w_buf);
> +
> + return 0;
> +}
> +
> +static int dw9768_release(struct dw9768_device *dw9768_dev)
> +{
> + unsigned char i;
> + int ret;
> +
> + char puSendCmdArray[4][2] = {
> + {0x02, 0x00}, {DW9768_REG_NULL, DW9768_REG_NULL},
> + {0x01, 0x00}, {DW9768_REG_NULL, DW9768_REG_NULL},
> + };
> +
> + for (i = 0; i < (sizeof(puSendCmdArray) / sizeof(char)) /
> + (sizeof(puSendCmdArray[0]) / sizeof(char)); i++) {> + if (puSendCmdArray[i][0] != DW9768_REG_NULL) {
> + ret = dw9768_i2c_write(dw9768_dev, puSendCmdArray[i],
> + DW9768_REG_VALUE_16BIT);
> + if (ret < 0)
> + return ret;
> + } else {
> + usleep_range(DW9768_CTRL_DELAY_US,
> + DW9768_CTRL_DELAY_US + 100);
> + }
> + }
Can we make this block more simple? I think the loop is not necessary.
> +
> + return 0;
> +}
> +
> +static int dw9768_init(struct dw9768_device *dw9768_dev)
> +{
> + unsigned char i;
> + int ret;
> +
> + char puSendCmdArray[5][2] = {
> + {0x02, 0x02}, {DW9768_REG_NULL, DW9768_REG_NULL},
> + {0x06, 0x41}, {0x07, 0x39}, {DW9768_REG_NULL, DW9768_REG_NULL},
> + };
> +
> + for (i = 0; i < (sizeof(puSendCmdArray) / sizeof(char)) /
> + (sizeof(puSendCmdArray[0]) / sizeof(char)); i++) {
> + if (puSendCmdArray[i][0] != DW9768_REG_NULL) {
> + ret = dw9768_i2c_write(dw9768_dev, puSendCmdArray[i],
> + DW9768_REG_VALUE_16BIT);
> + if (ret < 0)
> + return ret;
> + } else {
> + usleep_range(DW9768_CTRL_DELAY_US,
> + DW9768_CTRL_DELAY_US + 100);
> + }
> + }
Ditto.
> +
> + return 0;
> +}
> +
> +/*
> + * Power handling
> + */
> +static int dw9768_power_off(struct dw9768_device *dw9768_dev, bool standby)
> +{
> + struct i2c_client *client = v4l2_get_subdevdata(&dw9768_dev->sd);
> + int ret;
> +
> + /*
> + * Go to standby first as real power off my be denied by the hardware
typo? "may be denied"
> + * (single power line control for both dw9768_dev and sensor).
> + */
> + if (standby) {
> + dw9768_dev->standby = true;
> + ret = dw9768_release(dw9768_dev);
> + if (ret)
> + dev_err(&client->dev, "dw9768_release failed!\n");
> + }
> + ret = regulator_disable(dw9768_dev->analog_regulator);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int dw9768_power_on(struct dw9768_device *dw9768_dev, bool restore)
> +{
> + int ret;
> +
> + ret = regulator_enable(dw9768_dev->analog_regulator);
> + if (ret < 0)
> + return ret;
> +
> + if (restore) {
> + /* Restore the hardware settings. */
> + dw9768_dev->standby = false;
> + ret = dw9768_init(dw9768_dev);
> + if (ret < 0)
> + goto fail;
> + }
> +
> + return 0;
> +
> +fail:
> + dw9768_dev->standby = true;
> + regulator_disable(dw9768_dev->analog_regulator);
> +
> + return ret;
> +}
> +
> +/*
> + * Calculate status word and write it to the device based on current
> + * values of V4L2 controls. It is assumed that the stored V4L2 control
> + * values are properly limited and rounded.
> + */
> +static int dw9768_update_hw(struct dw9768_device *dw9768_dev, u16 val)
> +{
> + unsigned char i;
> + int ret;
> +
> + char puSendCmdArray[2][2] = {
> + {DW9768_REG_DAC_MSB, (char)(val >> DW9768_DAC_SHIFT)},
> + {DW9768_REG_DAC_LSB, (char)(val & 0xFF)},
> + };
> +
> + for (i = 0; i < (sizeof(puSendCmdArray) / sizeof(char)) /
> + (sizeof(puSendCmdArray[0]) / sizeof(char)); i++) {
> + ret = dw9768_i2c_write(dw9768_dev, puSendCmdArray[i],
> + DW9768_REG_VALUE_16BIT);
> + if (ret)
> + return ret;
> + }
ditto.
> +
> + return 0;
> +}
> +
> +static int dw9768_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct dw9768_device *dw9768_dev = to_dw9768_vcm(ctrl);
> +
> + if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
> + return dw9768_update_hw(dw9768_dev, ctrl->val);
> +
> + return 0;
> +}
> +
> +static const struct v4l2_ctrl_ops dw9768_vcm_ctrl_ops = {
> + .s_ctrl = dw9768_set_ctrl,
> +};
> +
> +static int
> +dw9768_set_power(struct v4l2_subdev *subdev, int on)
> +{
> + struct dw9768_device *dw9768_dev = sd_to_dw9768_vcm(subdev);
> + int ret = 0;
> +
> + mutex_lock(&dw9768_dev->power_lock);
> +
> + /*
> + * If the power count is modified from 0 to != 0 or from != 0 to 0,
> + * update the power state.
> + */
> + if (dw9768_dev->power_count == !on) {
> + ret = on ? dw9768_power_on(dw9768_dev, true) :
> + dw9768_power_off(dw9768_dev, true);
> + if (ret < 0)
> + goto done;
> + }
> +
> + /* Update the power count. */
> + dw9768_dev->power_count += on ? 1 : -1;
> + WARN_ON(dw9768_dev->power_count < 0);
> +
> +done:
> + mutex_unlock(&dw9768_dev->power_lock);
> + return ret;
> +}
> +
> +static int dw9768_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> +{
> + return dw9768_set_power(sd, 1);
> +}
> +
> +static int dw9768_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> +{
> + return dw9768_set_power(sd, 0);
> +}
I am a little confused about the pm control here.
Could we use the pm generic APIs to help do this?
> +
> +static const struct v4l2_subdev_internal_ops dw9768_int_ops = {
> + .open = dw9768_open,
> + .close = dw9768_close,
> +};
> +
> +static const struct v4l2_subdev_ops dw9768_ops = { };
> +
> +static void dw9768_subdev_cleanup(struct dw9768_device *dw9768_dev)
> +{
> + v4l2_async_unregister_subdev(&dw9768_dev->sd);
> + v4l2_ctrl_handler_free(&dw9768_dev->ctrls);
> + media_entity_cleanup(&dw9768_dev->sd.entity);
> +}
> +
> +static int dw9768_init_controls(struct dw9768_device *dw9768_dev)
> +{
> + struct v4l2_ctrl_handler *hdl = &dw9768_dev->ctrls;
> + const struct v4l2_ctrl_ops *ops = &dw9768_vcm_ctrl_ops;
> +
> + v4l2_ctrl_handler_init(hdl, 1);
> +
> + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
> + 0, DW9768_MAX_FOCUS_POS, DW9768_FOCUS_STEPS, 0);
> +
> + if (hdl->error) {
> + dev_err(dw9768_dev->sd.dev, "%s fail error: 0x%x\n",
> + __func__, hdl->error);
> + return hdl->error;
> + }
> +
> + dw9768_dev->sd.ctrl_handler = hdl;
> +
> + return 0;
> +}
> +
> +static int dw9768_probe(struct i2c_client *client)
> +{
> + struct device *dev = &client->dev;
> + struct dw9768_device *dw9768_dev;
> + int rval;
> +
> + dw9768_dev = devm_kzalloc(&client->dev, sizeof(*dw9768_dev),
> + GFP_KERNEL);
> + if (!dw9768_dev)
> + return -ENOMEM;
> +
> + dw9768_dev->analog_regulator = devm_regulator_get(dev, "afvdd");
> + if (IS_ERR(dw9768_dev->analog_regulator)) {
> + dev_err(dev, "cannot get analog regulator\n");
> + return PTR_ERR(dw9768_dev->analog_regulator);
> + }
> +
> + rval = regulator_set_voltage(dw9768_dev->analog_regulator,
> + DW9768_VOLTAGE_ANALOG,
> + DW9768_VOLTAGE_ANALOG);
> + if (rval < 0) {
> + dev_err(dev, "cannot set analog voltage\n");
> + return rval;
> + }
> +
> + mutex_init(&dw9768_dev->power_lock);
> +
> + v4l2_i2c_subdev_init(&dw9768_dev->sd, client, &dw9768_ops);
> + dw9768_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> + dw9768_dev->sd.internal_ops = &dw9768_int_ops;
> +
> + rval = dw9768_init_controls(dw9768_dev);
> + if (rval)
> + goto err_cleanup;
> +
> + rval = media_entity_pads_init(&dw9768_dev->sd.entity, 0, NULL);
> + if (rval < 0)
> + goto err_cleanup;
> +
> + dw9768_dev->sd.entity.function = MEDIA_ENT_F_LENS;
> +
> + rval = v4l2_async_register_subdev(&dw9768_dev->sd);
> + if (rval < 0)
> + goto err_cleanup;
> +
> + pm_runtime_set_active(dev);
> + pm_runtime_enable(dev);
> + pm_runtime_idle(dev);
> +
> + return 0;
> +
> +err_cleanup:
> + mutex_destroy(&dw9768_dev->power_lock);
> + dw9768_subdev_cleanup(dw9768_dev);
> + dev_err(dev, "Probe failed: %d\n", rval);
> + return rval;
> +}
> +
> +static int dw9768_remove(struct i2c_client *client)
> +{
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct dw9768_device *dw9768_dev = sd_to_dw9768_vcm(sd);
> +
> + pm_runtime_disable(&client->dev);
> + dw9768_subdev_cleanup(dw9768_dev);
> +
> + return 0;
> +}
> +
> +/*
> + * This function sets the vcm position, so it consumes least current
> + * The lens position is gradually moved in units of DW9768_CTRL_STEPS,
> + * to make the movements smoothly.
> + */
> +static int __maybe_unused dw9768_vcm_suspend(struct device *dev)
> +{
> + struct i2c_client *client = to_i2c_client(dev);
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct dw9768_device *dw9768_dev = sd_to_dw9768_vcm(sd);
> +
> + if (!dw9768_dev->power_count)
> + return 0;
> +
> + return dw9768_power_off(dw9768_dev, false);
> +}
> +
> +/*
> + * This function sets the vcm position to the value set by the user
> + * through v4l2_ctrl_ops s_ctrl handler
> + * The lens position is gradually moved in units of DW9768_CTRL_STEPS,
> + * to make the movements smoothly.
> + */
> +static int __maybe_unused dw9768_vcm_resume(struct device *dev)
> +{
> + struct i2c_client *client = to_i2c_client(dev);
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct dw9768_device *dw9768_dev = sd_to_dw9768_vcm(sd);
> +
> + if (!dw9768_dev->power_count)
> + return 0;
> +
> + return dw9768_power_on(dw9768_dev, true);
> +}
> +
> +static const struct i2c_device_id dw9768_id_table[] = {
> + { DW9768_NAME, 0 },
> + { { 0 } }
> +};
> +MODULE_DEVICE_TABLE(i2c, dw9768_id_table);
> +
> +static const struct of_device_id dw9768_of_table[] = {
> + { .compatible = "dongwoon,dw9768" },
> + { { 0 } }
> +};
> +MODULE_DEVICE_TABLE(of, dw9768_of_table);
> +
> +static const struct dev_pm_ops dw9768_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(dw9768_vcm_suspend, dw9768_vcm_resume)
> + SET_RUNTIME_PM_OPS(dw9768_vcm_suspend, dw9768_vcm_resume, NULL)
> +};
> +
> +static struct i2c_driver dw9768_i2c_driver = {
> + .driver = {
> + .name = DW9768_NAME,
> + .pm = &dw9768_pm_ops,
> + .of_match_table = dw9768_of_table,
> + },
> + .probe_new = dw9768_probe,
> + .remove = dw9768_remove,
> + .id_table = dw9768_id_table,
> +};
> +
> +module_i2c_driver(dw9768_i2c_driver);
> +
> +MODULE_AUTHOR("Dongchun Zhu <dongchun.zhu@mediatek.com>");
> +MODULE_DESCRIPTION("DW9768 VCM driver");
> +MODULE_LICENSE("GPL v2");
>
^ permalink raw reply
* RE: [PATCH v3 2/2] mailbox: introduce ARM SMC based mailbox
From: Peng Fan @ 2019-07-24 3:06 UTC (permalink / raw)
To: Peng Fan, robh+dt@kernel.org, mark.rutland@arm.com,
jassisinghbrar@gmail.com, sudeep.holla@arm.com,
andre.przywara@arm.com, f.fainelli@gmail.com
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, dl-linux-imx
In-Reply-To: <1563184103-8493-3-git-send-email-peng.fan@nxp.com>
Hi All,
> Subject: [PATCH v3 2/2] mailbox: introduce ARM SMC based mailbox
Any comments with this patch?
>
> From: Peng Fan <peng.fan@nxp.com>
>
> This mailbox driver implements a mailbox which signals transmitted data via
> an ARM smc (secure monitor call) instruction. The mailbox receiver is
> implemented in firmware and can synchronously return data when it returns
> execution to the non-secure world again.
> An asynchronous receive path is not implemented.
> This allows the usage of a mailbox to trigger firmware actions on SoCs which
> either don't have a separate management processor or on which such a core
> is not available. A user of this mailbox could be the SCP interface.
>
> Modified from Andre Przywara's v2 patch
> https://lore.kernel.org/patchwork/patch/812999/
>
> Cc: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>
> V3:
> Drop interrupt.
> Introduce transports for mem/reg usage.
> Add chan-id for mem usage.
>
> V2:
> Add interrupts notification support.
>
> drivers/mailbox/Kconfig | 7 ++
> drivers/mailbox/Makefile | 2 +
> drivers/mailbox/arm-smc-mailbox.c | 215
> ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 224 insertions(+)
> create mode 100644 drivers/mailbox/arm-smc-mailbox.c
>
> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index
> 595542bfae85..c3bd0f1ddcd8 100644
> --- a/drivers/mailbox/Kconfig
> +++ b/drivers/mailbox/Kconfig
> @@ -15,6 +15,13 @@ config ARM_MHU
> The controller has 3 mailbox channels, the last of which can be
> used in Secure mode only.
>
> +config ARM_SMC_MBOX
> + tristate "Generic ARM smc mailbox"
> + depends on OF && HAVE_ARM_SMCCC
> + help
> + Generic mailbox driver which uses ARM smc calls to call into
> + firmware for triggering mailboxes.
> +
> config IMX_MBOX
> tristate "i.MX Mailbox"
> depends on ARCH_MXC || COMPILE_TEST
> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index
> c22fad6f696b..93918a84c91b 100644
> --- a/drivers/mailbox/Makefile
> +++ b/drivers/mailbox/Makefile
> @@ -7,6 +7,8 @@ obj-$(CONFIG_MAILBOX_TEST) += mailbox-test.o
>
> obj-$(CONFIG_ARM_MHU) += arm_mhu.o
>
> +obj-$(CONFIG_ARM_SMC_MBOX) += arm-smc-mailbox.o
> +
> obj-$(CONFIG_IMX_MBOX) += imx-mailbox.o
>
> obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX) +=
> armada-37xx-rwtm-mailbox.o
> diff --git a/drivers/mailbox/arm-smc-mailbox.c
> b/drivers/mailbox/arm-smc-mailbox.c
> new file mode 100644
> index 000000000000..76a2ae11ee4d
> --- /dev/null
> +++ b/drivers/mailbox/arm-smc-mailbox.c
> @@ -0,0 +1,215 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2016,2017 ARM Ltd.
> + * Copyright 2019 NXP
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/mailbox_controller.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +
> +#define ARM_SMC_MBOX_MEM_TRANS BIT(0)
> +
> +struct arm_smc_chan_data {
> + u32 function_id;
> + u32 chan_id;
> + u32 flags;
> +};
> +
> +struct arm_smccc_mbox_cmd {
> + unsigned long a0, a1, a2, a3, a4, a5, a6, a7; };
> +
> +typedef unsigned long (smc_mbox_fn)(unsigned long, unsigned long,
> + unsigned long, unsigned long,
> + unsigned long, unsigned long,
> + unsigned long, unsigned long);
> +static smc_mbox_fn *invoke_smc_mbox_fn;
> +
> +static int arm_smc_send_data(struct mbox_chan *link, void *data) {
> + struct arm_smc_chan_data *chan_data = link->con_priv;
> + struct arm_smccc_mbox_cmd *cmd = data;
> + unsigned long ret;
> + u32 function_id;
> + u32 chan_id;
> +
> + if (chan_data->flags & ARM_SMC_MBOX_MEM_TRANS) {
> + if (chan_data->function_id != UINT_MAX)
> + function_id = chan_data->function_id;
> + else
> + function_id = cmd->a0;
> + chan_id = chan_data->chan_id;
> + ret = invoke_smc_mbox_fn(function_id, chan_id, 0, 0, 0, 0,
> + 0, 0);
> + } else {
> + ret = invoke_smc_mbox_fn(cmd->a0, cmd->a1, cmd->a2, cmd->a3,
> + cmd->a4, cmd->a5, cmd->a6, cmd->a7);
> + }
> +
> + mbox_chan_received_data(link, (void *)ret);
> +
> + return 0;
> +}
> +
> +static unsigned long __invoke_fn_hvc(unsigned long function_id,
> + unsigned long arg0, unsigned long arg1,
> + unsigned long arg2, unsigned long arg3,
> + unsigned long arg4, unsigned long arg5,
> + unsigned long arg6)
> +{
> + struct arm_smccc_res res;
> +
> + arm_smccc_hvc(function_id, arg0, arg1, arg2, arg3, arg4,
> + arg5, arg6, &res);
> + return res.a0;
> +}
> +
> +static unsigned long __invoke_fn_smc(unsigned long function_id,
> + unsigned long arg0, unsigned long arg1,
> + unsigned long arg2, unsigned long arg3,
> + unsigned long arg4, unsigned long arg5,
> + unsigned long arg6)
> +{
> + struct arm_smccc_res res;
> +
> + arm_smccc_smc(function_id, arg0, arg1, arg2, arg3, arg4,
> + arg5, arg6, &res);
> + return res.a0;
> +}
> +
> +static const struct mbox_chan_ops arm_smc_mbox_chan_ops = {
> + .send_data = arm_smc_send_data,
> +};
> +
> +static int arm_smc_mbox_probe(struct platform_device *pdev) {
> + struct device *dev = &pdev->dev;
> + struct mbox_controller *mbox;
> + struct arm_smc_chan_data *chan_data;
> + const char *method;
> + bool mem_trans = false;
> + int ret, i;
> + u32 val;
> +
> + if (!of_property_read_u32(dev->of_node, "arm,num-chans", &val)) {
> + if (!val) {
> + dev_err(dev, "invalid arm,num-chans value %u\n", val);
> + return -EINVAL;
> + }
> + } else {
> + return -EINVAL;
> + }
> +
> + if (!of_property_read_string(dev->of_node, "transports", &method)) {
> + if (!strcmp("mem", method)) {
> + mem_trans = true;
> + } else if (!strcmp("reg", method)) {
> + mem_trans = false;
> + } else {
> + dev_warn(dev, "invalid \"transports\" property: %s\n",
> + method);
> +
> + return -EINVAL;
> + }
> + } else {
> + return -EINVAL;
> + }
> +
> + if (!of_property_read_string(dev->of_node, "method", &method)) {
> + if (!strcmp("hvc", method)) {
> + invoke_smc_mbox_fn = __invoke_fn_hvc;
> + } else if (!strcmp("smc", method)) {
> + invoke_smc_mbox_fn = __invoke_fn_smc;
> + } else {
> + dev_warn(dev, "invalid \"method\" property: %s\n",
> + method);
> +
> + return -EINVAL;
> + }
> + } else {
> + return -EINVAL;
> + }
> +
> + mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
> + if (!mbox)
> + return -ENOMEM;
> +
> + mbox->num_chans = val;
> + mbox->chans = devm_kcalloc(dev, mbox->num_chans,
> sizeof(*mbox->chans),
> + GFP_KERNEL);
> + if (!mbox->chans)
> + return -ENOMEM;
> +
> + chan_data = devm_kcalloc(dev, mbox->num_chans, sizeof(*chan_data),
> + GFP_KERNEL);
> + if (!chan_data)
> + return -ENOMEM;
> +
> + for (i = 0; i < mbox->num_chans; i++) {
> + u32 function_id;
> +
> + ret = of_property_read_u32_index(dev->of_node,
> + "arm,func-ids", i,
> + &function_id);
> + if (ret)
> + chan_data[i].function_id = UINT_MAX;
> +
> + else
> + chan_data[i].function_id = function_id;
> +
> + chan_data[i].chan_id = i;
> +
> + if (mem_trans)
> + chan_data[i].flags |= ARM_SMC_MBOX_MEM_TRANS;
> + mbox->chans[i].con_priv = &chan_data[i];
> + }
> +
> + mbox->txdone_poll = false;
> + mbox->txdone_irq = false;
> + mbox->ops = &arm_smc_mbox_chan_ops;
> + mbox->dev = dev;
> +
> + platform_set_drvdata(pdev, mbox);
> +
> + ret = devm_mbox_controller_register(dev, mbox);
> + if (ret)
> + return ret;
> +
> + dev_info(dev, "ARM SMC mailbox enabled with %d chan%s.\n",
> + mbox->num_chans, mbox->num_chans == 1 ? "" : "s");
> +
> + return ret;
> +}
> +
> +static int arm_smc_mbox_remove(struct platform_device *pdev) {
> + struct mbox_controller *mbox = platform_get_drvdata(pdev);
> +
> + mbox_controller_unregister(mbox);
> + return 0;
> +}
> +
> +static const struct of_device_id arm_smc_mbox_of_match[] = {
> + { .compatible = "arm,smc-mbox", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, arm_smc_mbox_of_match);
> +
> +static struct platform_driver arm_smc_mbox_driver = {
> + .driver = {
> + .name = "arm-smc-mbox",
> + .of_match_table = arm_smc_mbox_of_match,
> + },
> + .probe = arm_smc_mbox_probe,
> + .remove = arm_smc_mbox_remove,
> +};
> +module_platform_driver(arm_smc_mbox_driver);
> +
> +MODULE_AUTHOR("Andre Przywara <andre.przywara@arm.com>");
> +MODULE_DESCRIPTION("Generic ARM smc mailbox driver");
> +MODULE_LICENSE("GPL v2");
Thanks,
Peng.
> --
> 2.16.4
^ permalink raw reply
* [PATCH v2 6/6] staging: mt7621-dts: add dt nodes for mt7621-pll
From: Chuanhong Guo @ 2019-07-24 2:23 UTC (permalink / raw)
To: open list:COMMON CLK FRAMEWORK,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, open list:MIPS, open list:STAGING SUBSYSTEM
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Ralf Baechle, Paul Burton, James Hogan, John Crispin,
Greg Kroah-Hartman, Weijie Gao, NeilBrown, Chuanhong Guo
In-Reply-To: <20190724022310.28010-1-gch981213@gmail.com>
This commit adds device-tree node for mt7621-pll and use its clocks
accordingly.
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
---
Changes since v1:
1. drop cpuclock node in gbpc1.dts
2. drop syscon in mt7621-pll node
drivers/staging/mt7621-dts/gbpc1.dts | 5 -----
drivers/staging/mt7621-dts/mt7621.dtsi | 15 +++++++--------
2 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/mt7621-dts/gbpc1.dts b/drivers/staging/mt7621-dts/gbpc1.dts
index 1fb560ff059c..d94b73243268 100644
--- a/drivers/staging/mt7621-dts/gbpc1.dts
+++ b/drivers/staging/mt7621-dts/gbpc1.dts
@@ -106,11 +106,6 @@
clock-frequency = <225000000>;
};
-&cpuclock {
- compatible = "fixed-clock";
- clock-frequency = <900000000>;
-};
-
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_pins>;
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index d89d68ffa7bc..7b82f7f70404 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -1,4 +1,5 @@
#include <dt-bindings/interrupt-controller/mips-gic.h>
+#include <dt-bindings/clock/mt7621-clk.h>
#include <dt-bindings/gpio/gpio.h>
/ {
@@ -27,12 +28,11 @@
serial0 = &uartlite;
};
- cpuclock: cpuclock@0 {
- #clock-cells = <0>;
- compatible = "fixed-clock";
+ pll: pll {
+ compatible = "mediatek,mt7621-pll";
- /* FIXME: there should be way to detect this */
- clock-frequency = <880000000>;
+ #clock-cells = <1>;
+ clock-output-names = "cpu", "bus";
};
sysclock: sysclock@0 {
@@ -155,7 +155,6 @@
compatible = "ns16550a";
reg = <0xc00 0x100>;
- clocks = <&sysclock>;
clock-frequency = <50000000>;
interrupt-parent = <&gic>;
@@ -172,7 +171,7 @@
compatible = "ralink,mt7621-spi";
reg = <0xb00 0x100>;
- clocks = <&sysclock>;
+ clocks = <&pll MT7621_CLK_BUS>;
resets = <&rstctrl 18>;
reset-names = "spi";
@@ -372,7 +371,7 @@
timer {
compatible = "mti,gic-timer";
interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
- clocks = <&cpuclock>;
+ clocks = <&pll MT7621_CLK_CPU>;
};
};
--
2.21.0
^ permalink raw reply related
* [PATCH v2 5/6] staging: mt7621-dts: fix register range of memc node in mt7621.dtsi
From: Chuanhong Guo @ 2019-07-24 2:23 UTC (permalink / raw)
To: open list:COMMON CLK FRAMEWORK,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, open list:MIPS, open list:STAGING SUBSYSTEM
Cc: Mark Rutland, Weijie Gao, Greg Kroah-Hartman, Stephen Boyd,
James Hogan, Michael Turquette, Ralf Baechle, Paul Burton,
Rob Herring, John Crispin, NeilBrown
In-Reply-To: <20190724022310.28010-1-gch981213@gmail.com>
The memc node from mt7621.dtsi has incorrect register resource.
Fix it according to the programming guide.
Signed-off-by: Weijie Gao <hackpascal@gmail.com>
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
---
Change since v1: None.
drivers/staging/mt7621-dts/mt7621.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index a4c08110094b..d89d68ffa7bc 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -138,7 +138,7 @@
memc: memc@5000 {
compatible = "mtk,mt7621-memc";
- reg = <0x300 0x100>;
+ reg = <0x5000 0x1000>;
};
cpc: cpc@1fbf0000 {
--
2.21.0
^ permalink raw reply related
* [PATCH v2 4/6] dt: bindings: add mt7621-pll dt binding documentation
From: Chuanhong Guo @ 2019-07-24 2:23 UTC (permalink / raw)
To: open list:COMMON CLK FRAMEWORK,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, open list:MIPS, open list:STAGING SUBSYSTEM
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
Ralf Baechle, Paul Burton, James Hogan, John Crispin,
Greg Kroah-Hartman, Weijie Gao, NeilBrown, Chuanhong Guo
In-Reply-To: <20190724022310.28010-1-gch981213@gmail.com>
This commit adds device tree binding documentation for MT7621
PLL controller.
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
---
Change since v1:
drop useless syscon in compatible string
.../bindings/clock/mediatek,mt7621-pll.txt | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt b/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
new file mode 100644
index 000000000000..7dcfbd5283e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7621-pll.txt
@@ -0,0 +1,18 @@
+Binding for Mediatek MT7621 PLL controller
+
+The PLL controller provides the 2 main clocks of the SoC: CPU and BUS.
+
+Required Properties:
+- compatible: has to be "mediatek,mt7621-pll"
+- #clock-cells: has to be one
+
+Optional properties:
+- clock-output-names: should be "cpu", "bus"
+
+Example:
+ pll {
+ compatible = "mediatek,mt7621-pll";
+
+ #clock-cells = <1>;
+ clock-output-names = "cpu", "bus";
+ };
--
2.21.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox