Re: [PATCH 0/3] ARM: dts: renesas: consistently use single space before =
On Fri, Jan 26, 2018 at 10:36:32AM +0100, Simon Horman wrote: > Consistently use a single space before a =. > > This series fixes instances where a tab is used instead. > > This is part of an ongoing effort to improve consistency within and between > the DT of Renesas SoCs to allow for easier comparison and maintenance. > > This series should not introduce any functional change. > > Based on renesas-devel-20180123-v4.15-rc9 I have applied this series with Geert's reviewed-by tags.
Re: [PATCH 0/2] ARM: dts: r8a774[35]: sort subnodes of soc node
On Fri, Jan 26, 2018 at 10:40:50AM +0100, Simon Horman wrote: > Sort the subnodes of the soc node to improve maintainability. > The sort key is the address on the bus with instances of the same > IP block grouped together and sorted alphabetically. > > Minor whitespace and line-wrapping changes are also made > to match the formatting of R-Car Gen2 SoCs. > > This is part of an ongoing effort to improve consistency within and between > the DT of Renesas SoCs to allow for easier comparison and maintenance. > > This patch should not introduce any functional change. > > Based on renesas-devel-20180123-v4.15-rc9 I have applied this series with Geert's reviewed-by tags.
Re: [PATCH 2/2] drm: adv7511: Add support for i2c_new_secondary_device
Hi Kieran, Thank you for the patch. On Monday, 22 January 2018 14:50:00 EET Kieran Bingham wrote: > The ADV7511 has four 256-byte maps that can be accessed via the main I²C > ports. Each map has it own I²C address and acts as a standard slave > device on the I²C bus. > > Allow a device tree node to override the default addresses so that > address conflicts with other devices on the same bus may be resolved at > the board description level. > > Signed-off-by: Kieran Bingham > --- > .../bindings/display/bridge/adi,adv7511.txt| 10 +- I don't mind personally, but device tree maintainers usually ask for DT bindings changes to be split to a separate patch. > drivers/gpu/drm/bridge/adv7511/adv7511.h | 4 +++ > drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 36 --- > 3 files changed, 37 insertions(+), 13 deletions(-) > > diff --git > a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt > b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt > index 0047b1394c70..f6bb9f6d3f48 100644 > --- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt > +++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt > @@ -70,6 +70,9 @@ Optional properties: >rather than generate its own timings for HDMI output. > - clocks: from common clock binding: reference to the CEC clock. > - clock-names: from common clock binding: must be "cec". > +- reg-names : Names of maps with programmable addresses. > + It can contain any map needing a non-default address. > + Possible maps names are : "main", "edid", "cec", "packet" Is the reg-names property (and the additional maps) mandatory or optional ? If mandatory you should also update the existing DT sources that use those bindings. If optional you should define which I2C addresses will be used when the maps are not specified (and in that case I think we should go for the addresses listed as default in the datasheet, which correspond to the current driver implementation when the main address is 0x3d/0x7a). You should also update the definition of the reg property that currently just states - reg: I2C slave address And finally you might want to define the term "map" in this context. Here's a proposal (if we make all maps mandatory). The ADV7511 internal registers are split into four pages exposed through different I2C addresses, creating four register maps. The I2C addresses of all four maps shall be specified by the reg and reg-names property. - reg: I2C slave addresses, one per reg-names entry - reg-names: map names, shall be "main", "edid", "cec", "packet" > Required nodes: > > @@ -88,7 +91,12 @@ Example > > adv7511w: hdmi@39 { > compatible = "adi,adv7511w"; > - reg = <39>; > + /* > + * The EDID page will be accessible on address 0x66 on the i2c > + * bus. All other maps continue to use their default addresses. > + */ > + reg = <0x39 0x66>; > + reg-names = "main", "edid"; > interrupt-parent = <&gpio3>; > interrupts = <29 IRQ_TYPE_EDGE_FALLING>; > clocks = <&cec_clock>; > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h > b/drivers/gpu/drm/bridge/adv7511/adv7511.h > index d034b2cb5eee..7d81ce3808e0 100644 > --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h > @@ -53,8 +53,10 @@ > #define ADV7511_REG_POWER0x41 > #define ADV7511_REG_STATUS 0x42 > #define ADV7511_REG_EDID_I2C_ADDR0x43 > +#define ADV7511_REG_EDID_I2C_ADDR_DEFAULT0x3f > #define ADV7511_REG_PACKET_ENABLE1 0x44 > #define ADV7511_REG_PACKET_I2C_ADDR 0x45 > +#define ADV7511_REG_PACKET_I2C_ADDR_DEFAULT 0x38 > #define ADV7511_REG_DSD_ENABLE 0x46 > #define ADV7511_REG_VIDEO_INPUT_CFG2 0x48 > #define ADV7511_REG_INFOFRAME_UPDATE 0x4a > @@ -89,6 +91,7 @@ > #define ADV7511_REG_TMDS_CLOCK_INV 0xde > #define ADV7511_REG_ARC_CTRL 0xdf > #define ADV7511_REG_CEC_I2C_ADDR 0xe1 > +#define ADV7511_REG_CEC_I2C_ADDR_DEFAULT 0x3c > #define ADV7511_REG_CEC_CTRL 0xe2 > #define ADV7511_REG_CHIP_ID_HIGH 0xf5 > #define ADV7511_REG_CHIP_ID_LOW 0xf6 > @@ -322,6 +325,7 @@ struct adv7511 { > struct i2c_client *i2c_main; > struct i2c_client *i2c_edid; > struct i2c_client *i2c_cec; > + struct i2c_client *i2c_packet; > > struct regmap *regmap; > struct regmap *regmap_cec; > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > index efa29db5fc2b..7ec33837752b 100644 > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > @@ -969,8 +969,8 @@ static int adv7511_init_cec_regmap(
Re: [PATCH v7 07/11] media: i2c: ov772x: Support frame interval handling
Hi Jacopo, Thank you for the patch. On Friday, 26 January 2018 15:55:26 EET Jacopo Mondi wrote: > Add support to ov772x driver for frame intervals handling and enumeration. > Tested with 10MHz and 24MHz input clock at VGA and QVGA resolutions for > 10, 15 and 30 frame per second rates. > > Signed-off-by: Jacopo Mondi > --- > drivers/media/i2c/ov772x.c | 315 +- > 1 file changed, 310 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c > index 912b1b9..6d46748 100644 > --- a/drivers/media/i2c/ov772x.c > +++ b/drivers/media/i2c/ov772x.c > @@ -250,6 +250,7 @@ > #define AEC_1p2 0x10 /* 01: 1/2 window */ > #define AEC_1p4 0x20 /* 10: 1/4 window */ > #define AEC_2p3 0x30 /* 11: Low 2/3 window */ > +#define COM4_RESERVED 0x01 /* Reserved value */ I'd write "Reserved bits", "Reserved value" makes it sound like it's the value of the full register. > /* COM5 */ > #define AFR_ON_OFF 0x80 /* Auto frame rate control ON/OFF selection */ > @@ -267,6 +268,19 @@ > /* AEC max step control */ > #define AEC_NO_LIMIT0x01 /* 0 : AEC incease step has limit */ > /* 1 : No limit to AEC increase step */ > +/* CLKRC */ > + /* Input clock divider register */ > +#define CLKRC_RESERVED 0x80 /* Reserved value */ > +#define CLKRC_BYPASS0x40 /* Bypass input clock divider */ > +#define CLKRC_DIV2 0x01 /* Divide input clock by 2 */ > +#define CLKRC_DIV3 0x02 /* Divide input clock by 3 */ > +#define CLKRC_DIV4 0x03 /* Divide input clock by 4 */ > +#define CLKRC_DIV5 0x04 /* Divide input clock by 5 */ > +#define CLKRC_DIV6 0x05 /* Divide input clock by 6 */ > +#define CLKRC_DIV8 0x07 /* Divide input clock by 8 */ > +#define CLKRC_DIV10 0x09 /* Divide input clock by 10 */ > +#define CLKRC_DIV16 0x0f /* Divide input clock by 16 */ > +#define CLKRC_DIV20 0x13 /* Divide input clock by 20 */ How about just #define CLKRC_DIV(n)((n) - 1) > /* COM7 */ > /* SCCB Register Reset */ > @@ -373,6 +387,12 @@ > #define VERSION(pid, ver) ((pid<<8)|(ver&0xFF)) > > /* > + * Input clock frequencies > + */ > +enum { OV772X_FIN_10MHz, OV772X_FIN_24MHz, OV772X_FIN_48MHz, OV772X_FIN_N, > }; > +static unsigned int ov772x_fin_vals[] = { 1000, 2400, 4800 > }; > + > +/* > * struct > */ > > @@ -391,6 +411,16 @@ struct ov772x_win_size { > struct v4l2_rect rect; > }; > > +struct ov772x_pclk_config { > + u8 com4; > + u8 clkrc; > +}; > + > +struct ov772x_frame_rate { > + unsigned int fps; > + const struct ov772x_pclk_config pclk[OV772X_FIN_N]; > +}; > + > struct ov772x_priv { > struct v4l2_subdevsubdev; > struct v4l2_ctrl_handler hdl; > @@ -404,6 +434,7 @@ struct ov772x_priv { > unsigned shortflag_hflip:1; > /* band_filter = COM8[5] ? 256 - BDBASE : 0 */ > unsigned shortband_filter; > + unsigned int fps; > }; > > /* > @@ -508,6 +539,154 @@ static const struct ov772x_win_size ov772x_win_sizes[] > = { }; > > /* > + * frame rate settings lists > + */ > +unsigned int ov772x_frame_intervals[] = {10, 15, 30, 60}; > +#define OV772X_N_FRAME_INTERVALS ARRAY_SIZE(ov772x_frame_intervals) > + > +static const struct ov772x_frame_rate vga_frame_rates[] = { > + { /* PCLK = 7,5 MHz */ > + .fps= 10, > + .pclk = { > + [OV772X_FIN_10MHz] = { > + .com4 = PLL_6x | COM4_RESERVED, > + .clkrc = CLKRC_DIV8 | CLKRC_RESERVED, > + }, > + [OV772X_FIN_24MHz] = { > + .com4 = PLL_BYPASS | COM4_RESERVED, > + .clkrc = CLKRC_DIV3 | CLKRC_RESERVED, > + }, > + [OV772X_FIN_48MHz] = { > + .com4 = PLL_BYPASS | COM4_RESERVED, > + .clkrc = CLKRC_DIV6 | CLKRC_RESERVED, > + }, > + }, > + }, > + { /* PCLK = 12 MHz */ > + .fps= 15, > + .pclk = { > + [OV772X_FIN_10MHz] = { > + .com4 = PLL_4x | COM4_RESERVED, > + .clkrc = CLKRC_DIV3 | CLKRC_RESERVED, > + }, > + [OV772X_FIN_24MHz] = { > + .com4 = PLL_BYPASS | COM4_RESERVED, > + .clkrc = CLKRC_DIV2 | CLKRC_RESERVED, > + }, > + [OV772X_FIN_48MHz] = { > + .com4 = PLL_BYPASS | COM4_RESERVED, > +
Re: [PATCH] sh: clk: Relax clk rate match test
Hi Jacopo, On Friday, 26 January 2018 18:24:54 EET jacopo mondi wrote: > On Thu, Jan 25, 2018 at 03:39:32PM +0100, Geert Uytterhoeven wrote: > > Hi Jacopo, > > [snip] > > --- > > drivers/sh/clk/core.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c > index 92863e3..d2cb94c 100644 > --- a/drivers/sh/clk/core.c > +++ b/drivers/sh/clk/core.c > @@ -198,9 +198,12 @@ int clk_rate_table_find(struct clk *clk, > { > struct cpufreq_frequency_table *pos; > > - cpufreq_for_each_valid_entry(pos, freq_table) > - if (pos->frequency == rate) > - return pos - freq_table; > + cpufreq_for_each_valid_entry(pos, freq_table) { > + if (pos->frequency > rate) > + continue; > >>> > >>> This assumes all frequency tables are sorted. > >>> > >>> Shouldn't you pick the closest frequency? > >>> > >>> However, that's what clk_rate_table_round() does, which is called from > >>> > >>> sh_clk_div_round_rate(), and thus already used as .round_rate: > >>> > >>> static struct sh_clk_ops sh_clk_div_enable_clk_ops = { > >>> .recalc = sh_clk_div_recalc, > >>> .set_rate = sh_clk_div_set_rate, > >>> .round_rate = sh_clk_div_round_rate, > >>> .enable = sh_clk_div_enable, > >>> .disable= sh_clk_div_disable, > >>> > >>> }; > >> > >> Does this implies clock rates should be set using clk_round_rate() and > >> not clk_set_rate() if I understand this right? > > > > Not necessarily... > > > > Note that both cpg_div6_clock_round_rate() and cpg_div6_clock_set_rate() > > in the CCF implementation for DIV6 clocks use rounding. > > Yeah but it doesn't seem to me that CCF implementation for DIV6 clocks does > have to walk static tables like the old sh clock driver does. They > perform rounding, but on the clock dividers given a requested rate > and the respective parent clock, if I'm not wrong. While clk_set_rate() doesn't explicitly document that the rate will be rounded, the clk_round_rate() documentation does: /** * clk_round_rate - adjust a rate to the exact rate a clock can provide * @clk: clock source * @rate: desired clock rate in Hz * * This answers the question "if I were to pass @rate to clk_set_rate(), * what clock rate would I end up with?" without changing the hardware * in any way. In other words: * * rate = clk_round_rate(clk, r); * * and: * * clk_set_rate(clk, r); * rate = clk_get_rate(clk); * * are equivalent except the former does not modify the clock hardware * in any way. * * Returns rounded clock rate in Hz, or negative errno. */ So I think the SH implementation of clk_set_rate() should round rates. (And feel free to send a patch for the clk_set_rate() documentation in include/linux/clk.h to state explicitly that the rate will be rounded). > Anyway, in this case a much simpler: > clk_set_rate(video_clk, clk_round_rate(video_clk, 1000)); > does the job for Migo-R. > > I will include this in next CEU iterations, since I already have a > small comment from you to fix there ;) That should not be needed, but if the above code is in a board file, I can live with that until drivers/sh/clk/ gets fixed. > >>> (clk_rate_table_find() is called from sh_clk_div_set_rate()) > >>> > >>> Or are you supposed to ask for the exact clock rate? Where does the 10 > >>> MHz come from? > >> > >> From board initialization code, in order to provide a valid input > >> clock to OV7720 sensor. -- Regards, Laurent Pinchart
Re: [PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote: > Hi Simon, > > On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman wrote: > > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote: > >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman > >> wrote: > >> > From: Takeshi Kihara > >> > > >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC. > >> > > >> > Signed-off-by: Takeshi Kihara > >> > Signed-off-by: Simon Horman > > >> As the CPG/MSSR driver now has suspend/resume support, do we need > >> a notifier to restore the Z or Z2 registers? Or is that handled > >> automatically > >> by cpufreq during system resume, for both the primary and the secondary > >> CPU cores? > > > > I am a bit unsure. > > > > When using the A57 cores, which is the default case, the Z clk is queried > > by CPUFreq on resume. It appears that on my system its already set to the > > correct value but I assume if it was not then it would be reset. However, > > this does not cover Z2 clk. So perhaps to be safe we need to register > > notifiers and make sure they they play nicely with CPUFreq? > > Of course the CPU is special: unlike many other devices, it must be running > when the kernel is reentered upon system resume. > It may be running using a different frequency setting, though. > However, following "opp-suspend", the system will always suspend with the > Z clock running at 1.5GHz, which is the default? > So Z is probably OK. > > It's more interesting to check what happens when the little cores are > enabled as well (unfortunately that requires different firmware). > 1. Does cpufreq handle them correctly when they are onlined again during >system resume? I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS using the instructions at https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support I also fleshed out the opts table for the little CPUs using the following from the 3.6.0 BSP: diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 1485e6a8e112..671c2d7ed6d0 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -219,7 +219,17 @@ compatible = "operating-points-v2"; opp-shared; - opp-12 { + opp@8 { + opp-hz = /bits/ 64 <8>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; + opp@10 { + opp-hz = /bits/ 64 <10>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; + opp@12 { opp-hz = /bits/ 64 <12>; opp-microvolt = <82>; clock-latency-ns = <30>; And fixed the out-by-one bug you pointed out elsewhere in this thread: diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index a7d68cefda9c..0c8fe10d57fe 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -94,7 +94,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, u32 val; val = clk_readl(zclk->reg) & zclk->mask; - mult = 32 - (val >> (__ffs(zclk->mask) - 1)); + mult = 32 - (val >> __ffs(zclk->mask)); /* Factor of 2 is for fixed divider */ return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * 2); @@ -129,7 +129,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, return -EBUSY; val = clk_readl(zclk->reg) & ~zclk->mask; - val |= ((32 - mult) << (__ffs(zclk->mask) - 1)) & zclk->mask; + val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask; clk_writel(val, zclk->reg); /* With these changes in place CPUFreq seems to work for both BIG and little CPUS. And the frequencies seem to be correct after S2RAM. # cd /sys/devices/system/cpu/ # grep . cpu*/cpufreq/scaling_available_frequencies cpu0/cpufreq/scaling_available_frequencies:50 100 150 ... cpu4/cpufreq/scaling_available_frequencies:80 100 120 ... # grep grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary grep: pll[01]|z|z2: No such file or directory # grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary z2 00 119808 0 0 .pll1 11 319488 0 0 .pll0 00 299520 0 0 z 00 149760 0 0 # echo 50 > cpu0/cpufreq/scaling_max_freq # echo 80 > cpu4/cpufreq/scaling_max_freq # grep . cpu*/cpufreq/*cur* cpu0/cpufreq/cpuinfo_cur_freq:468000 cpu0/cpufreq/scaling
Re: [PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
Hi Simon, On Mon, Jan 29, 2018 at 3:24 PM, Simon Horman wrote: > On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote: >> On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman wrote: >> > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote: >> >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman >> >> wrote: >> >> > From: Takeshi Kihara >> >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC. >> >> > >> >> > Signed-off-by: Takeshi Kihara >> >> > Signed-off-by: Simon Horman >> >> >> As the CPG/MSSR driver now has suspend/resume support, do we need >> >> a notifier to restore the Z or Z2 registers? Or is that handled >> >> automatically >> >> by cpufreq during system resume, for both the primary and the secondary >> >> CPU cores? >> > >> > I am a bit unsure. >> > >> > When using the A57 cores, which is the default case, the Z clk is queried >> > by CPUFreq on resume. It appears that on my system its already set to the >> > correct value but I assume if it was not then it would be reset. However, >> > this does not cover Z2 clk. So perhaps to be safe we need to register >> > notifiers and make sure they they play nicely with CPUFreq? >> >> Of course the CPU is special: unlike many other devices, it must be running >> when the kernel is reentered upon system resume. >> It may be running using a different frequency setting, though. >> However, following "opp-suspend", the system will always suspend with the >> Z clock running at 1.5GHz, which is the default? >> So Z is probably OK. >> >> It's more interesting to check what happens when the little cores are >> enabled as well (unfortunately that requires different firmware). >> 1. Does cpufreq handle them correctly when they are onlined again during >>system resume? > > I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS > using the instructions at > https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support > # grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary > z2 00 119808 > 0 0 >.pll1 11 319488 > 0 0 >.pll0 00 299520 > 0 0 > z 00 149760 > 0 0 You know it's PLL2, not PLL1, you want to look at? ;-) Thanks for checking, looks all good! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
On Mon, Jan 29, 2018 at 04:01:49PM +0100, Geert Uytterhoeven wrote: > Hi Simon, > > On Mon, Jan 29, 2018 at 3:24 PM, Simon Horman wrote: > > On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote: > >> On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman wrote: > >> > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote: > >> >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman > >> >> wrote: > >> >> > From: Takeshi Kihara > >> >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC. > >> >> > > >> >> > Signed-off-by: Takeshi Kihara > >> >> > Signed-off-by: Simon Horman > >> > >> >> As the CPG/MSSR driver now has suspend/resume support, do we need > >> >> a notifier to restore the Z or Z2 registers? Or is that handled > >> >> automatically > >> >> by cpufreq during system resume, for both the primary and the secondary > >> >> CPU cores? > >> > > >> > I am a bit unsure. > >> > > >> > When using the A57 cores, which is the default case, the Z clk is queried > >> > by CPUFreq on resume. It appears that on my system its already set to the > >> > correct value but I assume if it was not then it would be reset. However, > >> > this does not cover Z2 clk. So perhaps to be safe we need to register > >> > notifiers and make sure they they play nicely with CPUFreq? > >> > >> Of course the CPU is special: unlike many other devices, it must be running > >> when the kernel is reentered upon system resume. > >> It may be running using a different frequency setting, though. > >> However, following "opp-suspend", the system will always suspend with the > >> Z clock running at 1.5GHz, which is the default? > >> So Z is probably OK. > >> > >> It's more interesting to check what happens when the little cores are > >> enabled as well (unfortunately that requires different firmware). > >> 1. Does cpufreq handle them correctly when they are onlined again during > >>system resume? > > > > I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS > > using the instructions at > > https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support > > > # grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary > > z2 00 119808 > > 0 0 > >.pll1 11 319488 > > 0 0 > >.pll0 00 299520 > > 0 0 > > z 00 149760 > > 0 0 > > You know it's PLL2, not PLL1, you want to look at? ;-) Sorry, I will double check but I had looked at PLL2 earlier: I just messed things up when preparing things to post in email. > Thanks for checking, looks all good! Ok, so do you think we can merge this series with the off-by-one problem fixed?
[PATCH v2 0/5] R-Car D3 (r8a77995) I2C integration
Hi! This adds I2C controllers to the D3 device tree and enables I2C busses 0 and 1 on the Draak board. (I2C2 is not connected on that board.) This revision addresses Geert's review comments and adds Reviewed-Bys. See below for details. CU Uli Changes since v1: - pinctrl: patch dropped, has been picked up - i2c-rcar: patch dropped, redundant - dtsi: added dmac2 for i2c0-2 - dtsi: fixed internal SCL delays - dts: fixed EEPROM compatible string - bindings: added Rohm EEPROM - bindings: fixed typo in i2c-rcar bindings Ulrich Hecht (5): arm64: renesas: r8a77995: add I2C support arm64: renesas: draak: enable I2C controller 0 and EEPROM arm64: renesas: draak: enable I2C controller 1 i2c: rcar: document R8A77995 bindings dt-bindings: at24: add bindings for Rohm BR24T01 Documentation/devicetree/bindings/eeprom/at24.txt | 2 + Documentation/devicetree/bindings/i2c/i2c-rcar.txt | 1 + arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 28 + arch/arm64/boot/dts/renesas/r8a77995.dtsi | 67 ++ 4 files changed, 98 insertions(+) -- 2.7.4
[PATCH v2 5/5] dt-bindings: at24: add bindings for Rohm BR24T01
Both manufacturer and name variant. Signed-off-by: Ulrich Hecht --- Documentation/devicetree/bindings/eeprom/at24.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/eeprom/at24.txt b/Documentation/devicetree/bindings/eeprom/at24.txt index 1812c84..dd29937 100644 --- a/Documentation/devicetree/bindings/eeprom/at24.txt +++ b/Documentation/devicetree/bindings/eeprom/at24.txt @@ -40,6 +40,7 @@ Required properties: "microchip", "ramtron", "renesas", +"rohm", "nxp", "st", @@ -47,6 +48,7 @@ Required properties: variants of the above. Known such exceptions are listed below: "renesas,r1ex24002" - the fallback is "atmel,24c02" +"rohm,br24t01" - the fallback is "atmel,24c01" - reg: The I2C address of the EEPROM. -- 2.7.4
[PATCH v2 4/5] i2c: rcar: document R8A77995 bindings
R-Car D3 (R8A77995) SoC has a R-Car Gen3-compatible I2C controller. Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven --- Documentation/devicetree/bindings/i2c/i2c-rcar.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index a777477..e91dbaf 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -14,6 +14,7 @@ Required properties: "renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC. "renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC. "renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC. + "renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC. "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device. "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible device. -- 2.7.4
[PATCH v2 2/5] arm64: renesas: draak: enable I2C controller 0 and EEPROM
Enables EEPROM on I2C0 on the Draak board. Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index 09de73b..6ff9d3e 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -46,6 +46,11 @@ }; }; + i2c0_pins: i2c0 { + groups = "i2c0"; + function = "i2c0"; + }; + pwm0_pins: pwm0 { groups = "pwm0_c"; function = "pwm0"; @@ -67,6 +72,18 @@ }; }; +&i2c0 { + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; + + eeprom@50 { + compatible = "rohm,br24t01", "atmel,24c01"; + reg = <0x50>; + pagesize = <8>; + }; +}; + &ehci0 { status = "okay"; }; -- 2.7.4
Re: [PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
Hi Simon, On Mon, Jan 29, 2018 at 4:19 PM, Simon Horman wrote: > On Mon, Jan 29, 2018 at 04:01:49PM +0100, Geert Uytterhoeven wrote: >> On Mon, Jan 29, 2018 at 3:24 PM, Simon Horman wrote: >> > On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote: >> >> On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman wrote: >> >> > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote: >> >> >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman >> >> >> wrote: >> >> >> > From: Takeshi Kihara >> >> >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC. >> >> >> > >> >> >> > Signed-off-by: Takeshi Kihara >> >> >> > Signed-off-by: Simon Horman >> >> >> >> >> As the CPG/MSSR driver now has suspend/resume support, do we need >> >> >> a notifier to restore the Z or Z2 registers? Or is that handled >> >> >> automatically >> >> >> by cpufreq during system resume, for both the primary and the secondary >> >> >> CPU cores? >> >> > >> >> > I am a bit unsure. >> >> > >> >> > When using the A57 cores, which is the default case, the Z clk is >> >> > queried >> >> > by CPUFreq on resume. It appears that on my system its already set to >> >> > the >> >> > correct value but I assume if it was not then it would be reset. >> >> > However, >> >> > this does not cover Z2 clk. So perhaps to be safe we need to register >> >> > notifiers and make sure they they play nicely with CPUFreq? >> >> >> >> Of course the CPU is special: unlike many other devices, it must be >> >> running >> >> when the kernel is reentered upon system resume. >> >> It may be running using a different frequency setting, though. >> >> However, following "opp-suspend", the system will always suspend with the >> >> Z clock running at 1.5GHz, which is the default? >> >> So Z is probably OK. >> >> >> >> It's more interesting to check what happens when the little cores are >> >> enabled as well (unfortunately that requires different firmware). >> >> 1. Does cpufreq handle them correctly when they are onlined again during >> >>system resume? >> > >> > I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS >> > using the instructions at >> > https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support >> >> > # grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary >> > z2 00 119808 >> >0 0 >> >.pll1 11 319488 >> >0 0 >> >.pll0 00 299520 >> >0 0 >> > z 00 149760 >> >0 0 >> >> You know it's PLL2, not PLL1, you want to look at? ;-) > > Sorry, I will double check but I had looked at PLL2 earlier: > I just messed things up when preparing things to post in email. > >> Thanks for checking, looks all good! > > Ok, so do you think we can merge this series with > the off-by-one problem fixed? Yes we can. Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH v2 3/5] arm64: renesas: draak: enable I2C controller 1
No devices to add, I2C1 has an external connector only. Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index 6ff9d3e..af07da2 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -51,6 +51,11 @@ function = "i2c0"; }; + i2c1_pins: i2c1 { + groups = "i2c1"; + function = "i2c1"; + }; + pwm0_pins: pwm0 { groups = "pwm0_c"; function = "pwm0"; @@ -84,6 +89,12 @@ }; }; +&i2c1 { + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + &ehci0 { status = "okay"; }; -- 2.7.4
Re: [PATCH 5/6] arm64: renesas: draak: enable I2C controller 1
On Thu, Nov 16, 2017 at 10:31 AM, Geert Uytterhoeven wrote: > If no devices are connected, perhaps it's wise to defer the status update > to e.g. an overlay that describes what's connected to CN23? > > Or do you want it enabled to allow adding devices manually using > /sys/bus/i2c/devices/i2c-1/new_device? Indeed. It's an unpopulated bus on a development board with an external connector, so I think it's valid to assume that it is intended to be used for experimentation. CU Uli
[PATCH v2 1/5] arm64: renesas: r8a77995: add I2C support
Defines R-Car D3 I2C controllers 0-3. Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven --- arch/arm64/boot/dts/renesas/r8a77995.dtsi | 67 +++ 1 file changed, 67 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index 23f763b..22e633c 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -536,6 +536,73 @@ status = "disabled"; }; + i2c0: i2c@e650 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a77995", +"renesas,rcar-gen3-i2c"; + reg = <0 0xe650 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 931>; + power-domains = <&sysc R8A77995_PD_ALWAYS_ON>; + resets = <&cpg 931>; + dmas = <&dmac1 0x91>, <&dmac1 0x90>, + <&dmac2 0x91>, <&dmac2 0x90>; + dma-names = "tx", "rx", "tx", "rx"; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c1: i2c@e6508000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a77995", +"renesas,rcar-gen3-i2c"; + reg = <0 0xe6508000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 930>; + power-domains = <&sysc R8A77995_PD_ALWAYS_ON>; + resets = <&cpg 930>; + dmas = <&dmac1 0x93>, <&dmac1 0x92>, + <&dmac2 0x93>, <&dmac2 0x92>; + dma-names = "tx", "rx", "tx", "rx"; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c2: i2c@e651 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a77995", +"renesas,rcar-gen3-i2c"; + reg = <0 0xe651 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 929>; + power-domains = <&sysc R8A77995_PD_ALWAYS_ON>; + resets = <&cpg 929>; + dmas = <&dmac1 0x95>, <&dmac1 0x94>, + <&dmac2 0x95>, <&dmac2 0x94>; + dma-names = "tx", "rx", "tx", "rx"; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c3: i2c@e66d { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a77995", +"renesas,rcar-gen3-i2c"; + reg = <0 0xe66d 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 928>; + power-domains = <&sysc R8A77995_PD_ALWAYS_ON>; + resets = <&cpg 928>; + dmas = <&dmac0 0x97>, <&dmac0 0x96>; + dma-names = "tx", "rx"; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + pwm0: pwm@e6e3 { compatible = "renesas,pwm-r8a77995", "renesas,pwm-rcar"; reg = <0 0xe6e3 0 0x8>; -- 2.7.4
Re: [PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
On Mon, Jan 29, 2018 at 04:19:29PM +0100, Simon Horman wrote: > On Mon, Jan 29, 2018 at 04:01:49PM +0100, Geert Uytterhoeven wrote: > > Hi Simon, > > > > On Mon, Jan 29, 2018 at 3:24 PM, Simon Horman wrote: > > > On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote: > > >> On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman wrote: > > >> > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote: > > >> >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman > > >> >> wrote: > > >> >> > From: Takeshi Kihara > > >> >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC. > > >> >> > > > >> >> > Signed-off-by: Takeshi Kihara > > >> >> > Signed-off-by: Simon Horman > > >> > > >> >> As the CPG/MSSR driver now has suspend/resume support, do we need > > >> >> a notifier to restore the Z or Z2 registers? Or is that handled > > >> >> automatically > > >> >> by cpufreq during system resume, for both the primary and the > > >> >> secondary > > >> >> CPU cores? > > >> > > > >> > I am a bit unsure. > > >> > > > >> > When using the A57 cores, which is the default case, the Z clk is > > >> > queried > > >> > by CPUFreq on resume. It appears that on my system its already set to > > >> > the > > >> > correct value but I assume if it was not then it would be reset. > > >> > However, > > >> > this does not cover Z2 clk. So perhaps to be safe we need to register > > >> > notifiers and make sure they they play nicely with CPUFreq? > > >> > > >> Of course the CPU is special: unlike many other devices, it must be > > >> running > > >> when the kernel is reentered upon system resume. > > >> It may be running using a different frequency setting, though. > > >> However, following "opp-suspend", the system will always suspend with the > > >> Z clock running at 1.5GHz, which is the default? > > >> So Z is probably OK. > > >> > > >> It's more interesting to check what happens when the little cores are > > >> enabled as well (unfortunately that requires different firmware). > > >> 1. Does cpufreq handle them correctly when they are onlined again during > > >>system resume? > > > > > > I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS > > > using the instructions at > > > https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support > > > > > # grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary > > > z2 00 119808 > > > 0 0 > > >.pll1 11 319488 > > > 0 0 > > >.pll0 00 299520 > > > 0 0 > > > z 00 149760 > > > 0 0 > > > > You know it's PLL2, not PLL1, you want to look at? ;-) > > Sorry, I will double check but I had looked at PLL2 earlier: > I just messed things up when preparing things to post in email. I checked, PLL2 is constant at 239616 across the test described in my earlier email. > > Thanks for checking, looks all good! > > Ok, so do you think we can merge this series with > the off-by-one problem fixed? >
Re: [PATCH v2 5/5] dt-bindings: at24: add bindings for Rohm BR24T01
On Mon, Jan 29, 2018 at 4:45 PM, Ulrich Hecht wrote: > Both manufacturer and name variant. > > Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
On Mon, Jan 29, 2018 at 04:51:35PM +0100, Simon Horman wrote: > On Mon, Jan 29, 2018 at 04:19:29PM +0100, Simon Horman wrote: > > On Mon, Jan 29, 2018 at 04:01:49PM +0100, Geert Uytterhoeven wrote: > > > Hi Simon, > > > > > > On Mon, Jan 29, 2018 at 3:24 PM, Simon Horman wrote: > > > > On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote: > > > >> On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman > > > >> wrote: > > > >> > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote: > > > >> >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman > > > >> >> wrote: > > > >> >> > From: Takeshi Kihara > > > >> >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC. > > > >> >> > > > > >> >> > Signed-off-by: Takeshi Kihara > > > >> >> > Signed-off-by: Simon Horman > > > >> > > > >> >> As the CPG/MSSR driver now has suspend/resume support, do we need > > > >> >> a notifier to restore the Z or Z2 registers? Or is that handled > > > >> >> automatically > > > >> >> by cpufreq during system resume, for both the primary and the > > > >> >> secondary > > > >> >> CPU cores? > > > >> > > > > >> > I am a bit unsure. > > > >> > > > > >> > When using the A57 cores, which is the default case, the Z clk is > > > >> > queried > > > >> > by CPUFreq on resume. It appears that on my system its already set > > > >> > to the > > > >> > correct value but I assume if it was not then it would be reset. > > > >> > However, > > > >> > this does not cover Z2 clk. So perhaps to be safe we need to register > > > >> > notifiers and make sure they they play nicely with CPUFreq? > > > >> > > > >> Of course the CPU is special: unlike many other devices, it must be > > > >> running > > > >> when the kernel is reentered upon system resume. > > > >> It may be running using a different frequency setting, though. > > > >> However, following "opp-suspend", the system will always suspend with > > > >> the > > > >> Z clock running at 1.5GHz, which is the default? > > > >> So Z is probably OK. > > > >> > > > >> It's more interesting to check what happens when the little cores are > > > >> enabled as well (unfortunately that requires different firmware). > > > >> 1. Does cpufreq handle them correctly when they are onlined again > > > >> during > > > >>system resume? > > > > > > > > I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS > > > > using the instructions at > > > > https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support > > > > > > > # grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary > > > > z2 00 119808 > > > > 0 0 > > > >.pll1 11 319488 > > > > 0 0 > > > >.pll0 00 299520 > > > > 0 0 > > > > z 00 149760 > > > > 0 0 > > > > > > You know it's PLL2, not PLL1, you want to look at? ;-) > > > > Sorry, I will double check but I had looked at PLL2 earlier: > > I just messed things up when preparing things to post in email. > > I checked, PLL2 is constant at 239616 across the test described > in my earlier email. I have now been able to reproduce an equivalent result on an M3W ES1.0 / Salvator-X. > > > Thanks for checking, looks all good! > > > > Ok, so do you think we can merge this series with > > the off-by-one problem fixed?
[PATCH v10 00/30] rcar-vin: Add Gen3 with media controller
Hi, This series adds Gen3 VIN support to rcar-vin driver for Renesas r8a7795, r8a7796 and r8a77970. It is based on the media-tree and depends on Fabrizio Castro patches as they touches the order of the compatible strings in the documentation to reduce merge conflicts. The dependencies are: [PATCH v2 1/4] dt-bindings: media: rcar_vin: Reverse SoC part number list [PATCH v2 2/4] dt-bindings: media: rcar_vin: add device tree support for r8a774[35] The driver is tested on Renesas H3 (r8a7795, ES2.0), M3-W (r8a7796) together with the rcar-csi2 driver (posted separately and not yet upstream) and the Salvator-X onboard ADV7482. It is also tested on the V3M (r8a77970) on the Eagle board together with its expansion board with a ADV7482 and out of tree patches for GMSL capture using the max9286 and rdacm20 drivers. It is possible to capture both CVBS and HDMI video streams, v4l2-compliance passes with no errors and media-ctl can be used to change the routing and formats for the different entities in the media graph. Gen2 compatibility is verified on Koelsch and no problems where found, video can be captured just like before and v4l2-compliance passes without errors or warnings just like before this series. I have started on a very basic test suite for the VIN driver at: https://git.ragnatech.se/vin-tests And as before the state of the driver and information about how to test it can be found on the elinux wiki: http://elinux.org/R-Car/Tests:rcar-vin * Changes since v9 - Fixed mistakes in the device tree description pointed out by Laurent. - GenX -> GenX platforms - portX -> port X - Explicitly state the on Gen3 platforms port 0 can only describe one endpoint and that only VIN instances connected to external pins should have a port 0 node. - s/which is/connected to/ in he endpoint description for Gen3 platforms. - Update some poorly written commit messages. - Moved the digital subdevice attach and detach code to two separate functions to increase readability. - Rename the struct rvin_info member chip to model to better describe its purpose. - Change the video name from "rcar_vin e6ef.video" to "VINx output" where x is the VIN id. - Dropped patch 'rcar-vin: do not allow changing scaling and composing while streaming' as it removed Gen2 functionality which is valid as pointed out by Laurent. - Rename rvin_get_sd_format() to rvin_get_source_format() and change its parameter from struct v4l2_pix_format* to struct v4l2_mbus_framefmt*. - Clarified commit message and add a few move comments to 'rcar-vin: fix handling of single field frames (top, bottom and alternate fields'. - Update documentation for struct rvin_dev fields mbus_cfg and code. - Fix argument in VNCSI_IFMD_CSI_CHSEL macro. - Renamed rvin_set_chsel() to rvin_set_channel_routing(). - Restore the VNMC register after changing CHSEL setting. - Broke patch 'rcar-vin: break out format alignment and checking' into three parts to ease review. - Add new patch to introduce a default field. - Only include media/v4l2-mc.h in the .c files that needs it and not in rcar-vin.h. - Rename rvin_group_allocate() rvin_group_get() - Rename rvin_group_delete() rvin_group_put() - Updated error message "VIN number %d already occupied\n" to "Duplicate renesas,id property value %u\n". - Removed dev_dbg messages which only where useful during development. - Dropped patch '[PATCH v9 10/28] rcar-vin: do not reset crop and compose when setting format' as it introduces a regression on Gen2. - Inline rvin_group_read_id() and rvin_group_add_vin() into rvin_group_get(). - Define static variables at the top of rcar-core.c. - Fix potential deadlock in rvin_group_get(). - Set media device model name to the VIN module name. - Set media device model to matched complicity string. - Do not use a 2 dimensional sparse array for chsel values in struct rvin_info, instead use a flat array and store VIN and CHSEL value inside each array item. - Reworked DT parsing code to make use of the new v4l2_async_notifier_parse_fwnode_endpoints_by_port() helper removing a lot of iffy custom parsing code. - Rework how CHSEL value is calculated in the link notifier callback. Using a bitmap of possible values instead of looping over an array turned out great reducing both LoC and increasing readability of the code which was a bit difficult before. It also reduced to memory needed to contain the static routing information. - Verify the media bus pixel code when starting a stream. - Take the media device graph lock when figuring out and starting a stream so not to race between simultaneous stream start from multiple rcar-vin instances as they might share common subdevices. - Added review tags from Laurent. - Dropped tags from patches that where changed more then just correcting spelling or other gramma errors. * Changes since v8 - Fixed issue in rvin_group_init() where rvin_group_update_links()
[PATCH v10 01/30] rcar-vin: add Gen3 devicetree bindings documentation
Document the devicetree bindings for the CSI-2 inputs available on Gen3. There is a need to add a custom property 'renesas,id' and to define which CSI-2 input is described in which endpoint under the port@1 node. This information is needed since there are a set of predefined routes between each VIN and CSI-2 block. This routing table will be kept inside the driver but in order for it to act on it it must know which VIN and CSI-2 is which. Signed-off-by: Niklas Söderlund Acked-by: Rob Herring --- .../devicetree/bindings/media/rcar_vin.txt | 118 ++--- 1 file changed, 106 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index c60e6b0a89b67a8c..90d92836284b7f68 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -2,8 +2,12 @@ Renesas R-Car Video Input driver (rcar_vin) --- The rcar_vin device provides video input capabilities for the Renesas R-Car -family of devices. The current blocks are always slaves and suppot one input -channel which can be either RGB, YUYV or BT656. +family of devices. + +Each VIN instance has a single parallel input that supports RGB and YUV video, +with both external synchronization and BT.656 synchronization for the latter. +Depending on the instance the VIN input is connected to external SoC pins, or +on Gen3 platforms to a CSI-2 receiver. - compatible: Must be one or more of the following - "renesas,vin-r8a7743" for the R8A7743 device @@ -16,6 +20,8 @@ channel which can be either RGB, YUYV or BT656. - "renesas,vin-r8a7793" for the R8A7793 device - "renesas,vin-r8a7794" for the R8A7794 device - "renesas,vin-r8a7795" for the R8A7795 device + - "renesas,vin-r8a7796" for the R8A7796 device + - "renesas,vin-r8a77970" for the R8A77970 device - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 or RZ/G1 compatible device. - "renesas,rcar-gen3-vin" for a generic R-Car Gen3 compatible device. @@ -31,21 +37,38 @@ channel which can be either RGB, YUYV or BT656. Additionally, an alias named vinX will need to be created to specify which video input device this is. -The per-board settings: +The per-board settings Gen2 platforms: - port sub-node describing a single endpoint connected to the vin as described in video-interfaces.txt[1]. Only the first one will be considered as each vin interface has one input port. - These settings are used to work out video input format and widths - into the system. +The per-board settings Gen3 platforms: +Gen3 platforms can support both a single connected parallel input source +from external SoC pins (port0) and/or multiple parallel input sources +from local SoC CSI-2 receivers (port1) depending on SoC. -Device node example +- renesas,id - ID number of the VIN, VINx in the documentation. +- ports +- port 0 - sub-node describing a single endpoint connected to the VIN + from external SoC pins described in video-interfaces.txt[1]. + Describing more then one endpoint in port 0 is invalid. Only VIN + instances that are connected to external pins should have port 0. +- port 1 - sub-nodes describing one or more endpoints connected to + the VIN from local SoC CSI-2 receivers. The endpoint numbers must + use the following schema. - aliases { - vin0 = &vin0; - }; +- Endpoint 0 - sub-node describing the endpoint connected to CSI20 +- Endpoint 1 - sub-node describing the endpoint connected to CSI21 +- Endpoint 2 - sub-node describing the endpoint connected to CSI40 +- Endpoint 3 - sub-node describing the endpoint connected to CSI41 + +Device node example for Gen2 platforms +-- + +aliases { +vin0 = &vin0; +}; vin0: vin@e6ef { compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; @@ -55,8 +78,8 @@ Device node example status = "disabled"; }; -Board setup example (vin1 composite video input) - +Board setup example for Gen2 platforms (vin1 composite video input) +--- &i2c2 { status = "ok"; @@ -95,6 +118,77 @@ Board setup example (vin1 composite video input) }; }; +Device node example for Gen3 platforms +-- +vin0: video@e6ef { +compatible = "renesas,vin-r8a7795"; +reg = <0 0xe6ef 0 0x1000>; +interrupts = ; +clocks = <&cpg CPG_MOD 811>; +power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; +resets = <&cpg 811>; +renesas,id = <0>; + +
[PATCH v10 02/30] rcar-vin: rename poorly named initialize and cleanup functions
The functions to register and unregister the hardware and video device where poorly named from the start. Rename them to better describe their intended function. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 10 +- drivers/media/platform/rcar-vin/rcar-dma.c | 6 +++--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 4 ++-- drivers/media/platform/rcar-vin/rcar-vin.h | 8 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index f1fc7978d6d1523d..2bedf20abcf3ca07 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -93,7 +93,7 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) return ret; } - return rvin_v4l2_probe(vin); + return rvin_v4l2_register(vin); } static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, @@ -103,7 +103,7 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, struct rvin_dev *vin = notifier_to_vin(notifier); vin_dbg(vin, "unbind digital subdev %s\n", subdev->name); - rvin_v4l2_remove(vin); + rvin_v4l2_unregister(vin); vin->digital->subdev = NULL; } @@ -245,7 +245,7 @@ static int rcar_vin_probe(struct platform_device *pdev) if (irq < 0) return irq; - ret = rvin_dma_probe(vin, irq); + ret = rvin_dma_register(vin, irq); if (ret) return ret; @@ -260,7 +260,7 @@ static int rcar_vin_probe(struct platform_device *pdev) return 0; error: - rvin_dma_remove(vin); + rvin_dma_unregister(vin); v4l2_async_notifier_cleanup(&vin->notifier); return ret; @@ -275,7 +275,7 @@ static int rcar_vin_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(&vin->notifier); v4l2_async_notifier_cleanup(&vin->notifier); - rvin_dma_remove(vin); + rvin_dma_unregister(vin); return 0; } diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 23fdff7a7370842e..d701b52d198243b5 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1153,14 +1153,14 @@ static const struct vb2_ops rvin_qops = { .wait_finish= vb2_ops_wait_finish, }; -void rvin_dma_remove(struct rvin_dev *vin) +void rvin_dma_unregister(struct rvin_dev *vin) { mutex_destroy(&vin->lock); v4l2_device_unregister(&vin->v4l2_dev); } -int rvin_dma_probe(struct rvin_dev *vin, int irq) +int rvin_dma_register(struct rvin_dev *vin, int irq) { struct vb2_queue *q = &vin->queue; int i, ret; @@ -1208,7 +1208,7 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq) return 0; error: - rvin_dma_remove(vin); + rvin_dma_unregister(vin); return ret; } diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index b479b882da12f62d..178aecc94962abe2 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -839,7 +839,7 @@ static const struct v4l2_file_operations rvin_fops = { .read = vb2_fop_read, }; -void rvin_v4l2_remove(struct rvin_dev *vin) +void rvin_v4l2_unregister(struct rvin_dev *vin) { v4l2_info(&vin->v4l2_dev, "Removing %s\n", video_device_node_name(&vin->vdev)); @@ -866,7 +866,7 @@ static void rvin_notify(struct v4l2_subdev *sd, } } -int rvin_v4l2_probe(struct rvin_dev *vin) +int rvin_v4l2_register(struct rvin_dev *vin) { struct video_device *vdev = &vin->vdev; struct v4l2_subdev *sd = vin_to_source(vin); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 5382078143fb3869..85cb7ec53d2b08b5 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -153,11 +153,11 @@ struct rvin_dev { #define vin_warn(d, fmt, arg...) dev_warn(d->dev, fmt, ##arg) #define vin_err(d, fmt, arg...)dev_err(d->dev, fmt, ##arg) -int rvin_dma_probe(struct rvin_dev *vin, int irq); -void rvin_dma_remove(struct rvin_dev *vin); +int rvin_dma_register(struct rvin_dev *vin, int irq); +void rvin_dma_unregister(struct rvin_dev *vin); -int rvin_v4l2_probe(struct rvin_dev *vin); -void rvin_v4l2_remove(struct rvin_dev *vin); +int rvin_v4l2_register(struct rvin_dev *vin); +void rvin_v4l2_unregister(struct rvin_dev *vin); const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); -- 2.16.1
[PATCH v10 03/30] rcar-vin: unregister video device on driver removal
If the video device was registered by the complete() callback it should be unregistered when a device is unbound from the driver. Protect from printing an uninitialized video device node name by adding a check in rvin_v4l2_unregister() to identify that the video device is registered. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Acked-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 2 ++ drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 2bedf20abcf3ca07..47f06acde2e698f2 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -272,6 +272,8 @@ static int rcar_vin_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); + rvin_v4l2_unregister(vin); + v4l2_async_notifier_unregister(&vin->notifier); v4l2_async_notifier_cleanup(&vin->notifier); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 178aecc94962abe2..32a658214f48fa49 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -841,6 +841,9 @@ static const struct v4l2_file_operations rvin_fops = { void rvin_v4l2_unregister(struct rvin_dev *vin) { + if (!video_is_registered(&vin->vdev)) + return; + v4l2_info(&vin->v4l2_dev, "Removing %s\n", video_device_node_name(&vin->vdev)); -- 2.16.1
[PATCH v10 08/30] rcar-vin: all Gen2 boards can scale simplify logic
The logic to preserve the requested format width and height are too complex and come from a premature optimization for Gen3. All Gen2 SoC can scale and the Gen3 implementation will not use these functions at all so simply preserve the width and height when interacting with the subdevice much like the field is preserved simplifies the logic quite a bit. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-dma.c | 8 drivers/media/platform/rcar-vin/rcar-v4l2.c | 25 +++-- drivers/media/platform/rcar-vin/rcar-vin.h | 2 -- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index a7cda3922cb74baa..fd14be20a6604d7a 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -585,14 +585,6 @@ void rvin_crop_scale_comp(struct rvin_dev *vin) 0, 0); } -void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix, - u32 width, u32 height) -{ - /* All VIN channels on Gen2 have scalers */ - pix->width = width; - pix->height = height; -} - /* - * Hardware setup */ diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 8805d7911a761019..c2265324c7c96308 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -166,6 +166,7 @@ static int __rvin_try_format_source(struct rvin_dev *vin, .which = which, }; enum v4l2_field field; + u32 width, height; int ret; sd = vin_to_source(vin); @@ -178,7 +179,10 @@ static int __rvin_try_format_source(struct rvin_dev *vin, format.pad = vin->digital->source_pad; + /* Allow the video device to override field and to scale */ field = pix->field; + width = pix->width; + height = pix->height; ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, &format); if (ret < 0 && ret != -ENOIOCTLCMD) @@ -186,11 +190,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin, v4l2_fill_pix_format(pix, &format.format); - pix->field = field; - source->width = pix->width; source->height = pix->height; + pix->field = field; + pix->width = width; + pix->height = height; + vin_dbg(vin, "Source resolution: %ux%u\n", source->width, source->height); @@ -204,13 +210,9 @@ static int __rvin_try_format(struct rvin_dev *vin, struct v4l2_pix_format *pix, struct rvin_source_fmt *source) { - u32 rwidth, rheight, walign; + u32 walign; int ret; - /* Requested */ - rwidth = pix->width; - rheight = pix->height; - /* Keep current field if no specific one is asked for */ if (pix->field == V4L2_FIELD_ANY) pix->field = vin->format.field; @@ -248,10 +250,6 @@ static int __rvin_try_format(struct rvin_dev *vin, break; } - /* If source can't match format try if VIN can scale */ - if (source->width != rwidth || source->height != rheight) - rvin_scale_try(vin, pix, rwidth, rheight); - /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; @@ -270,9 +268,8 @@ static int __rvin_try_format(struct rvin_dev *vin, return -EINVAL; } - vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n", - rwidth, rheight, pix->width, pix->height, - pix->bytesperline, pix->sizeimage); + vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", + pix->width, pix->height, pix->bytesperline, pix->sizeimage); return 0; } diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index f195d174eeacda10..8daba9db0e927a49 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -175,8 +175,6 @@ void rvin_v4l2_unregister(struct rvin_dev *vin); const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); /* Cropping, composing and scaling */ -void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix, - u32 width, u32 height); void rvin_crop_scale_comp(struct rvin_dev *vin); #endif -- 2.16.1
[PATCH v10 09/30] rcar-vin: read subdevice format for crop only when needed
Instead of caching the subdevice format each time the video device format is set read it directly when it's needed. As it turns out the format is only needed when figuring out the max rectangle for cropping. This simplifies the code and makes it clearer what the source format is used for. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 112 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 12 --- 2 files changed, 61 insertions(+), 63 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index c2265324c7c96308..4d5be2d0c79c9c9a 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -90,35 +90,54 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) * V4L2 */ -static void rvin_reset_crop_compose(struct rvin_dev *vin) +static int rvin_get_source_format(struct rvin_dev *vin, + struct v4l2_mbus_framefmt *mbus_fmt) { + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = vin->digital->source_pad, + }; + int ret; + + ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt); + if (ret) + return ret; + + memcpy(mbus_fmt, &fmt.format, sizeof(*mbus_fmt)); + + return 0; +} + +static int rvin_reset_crop_compose(struct rvin_dev *vin) +{ + struct v4l2_mbus_framefmt source_fmt; + int ret; + + ret = rvin_get_source_format(vin, &source_fmt); + if (ret) + return ret; + vin->crop.top = vin->crop.left = 0; - vin->crop.width = vin->source.width; - vin->crop.height = vin->source.height; + vin->crop.width = source_fmt.width; + vin->crop.height = source_fmt.height; vin->compose.top = vin->compose.left = 0; vin->compose.width = vin->format.width; vin->compose.height = vin->format.height; + + return 0; } static int rvin_reset_format(struct rvin_dev *vin) { - struct v4l2_subdev_format fmt = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - }; - struct v4l2_mbus_framefmt *mf = &fmt.format; + struct v4l2_mbus_framefmt source_fmt; int ret; - fmt.pad = vin->digital->source_pad; - - ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt); + ret = rvin_get_source_format(vin, &source_fmt); if (ret) return ret; - vin->format.width = mf->width; - vin->format.height = mf->height; - vin->format.colorspace = mf->colorspace; - vin->format.field = mf->field; + v4l2_fill_pix_format(&vin->format, &source_fmt); /* * If the subdevice uses ALTERNATE field mode and G_STD is @@ -147,7 +166,9 @@ static int rvin_reset_format(struct rvin_dev *vin) break; } - rvin_reset_crop_compose(vin); + ret = rvin_reset_crop_compose(vin); + if (ret) + return ret; vin->format.bytesperline = rvin_format_bytesperline(&vin->format); vin->format.sizeimage = rvin_format_sizeimage(&vin->format); @@ -156,9 +177,7 @@ static int rvin_reset_format(struct rvin_dev *vin) } static int __rvin_try_format_source(struct rvin_dev *vin, - u32 which, - struct v4l2_pix_format *pix, - struct rvin_source_fmt *source) + u32 which, struct v4l2_pix_format *pix) { struct v4l2_subdev *sd; struct v4l2_subdev_pad_config *pad_cfg; @@ -190,25 +209,16 @@ static int __rvin_try_format_source(struct rvin_dev *vin, v4l2_fill_pix_format(pix, &format.format); - source->width = pix->width; - source->height = pix->height; - pix->field = field; pix->width = width; pix->height = height; - - vin_dbg(vin, "Source resolution: %ux%u\n", source->width, - source->height); - done: v4l2_subdev_free_pad_config(pad_cfg); return ret; } static int __rvin_try_format(struct rvin_dev *vin, -u32 which, -struct v4l2_pix_format *pix, -struct rvin_source_fmt *source) +u32 which, struct v4l2_pix_format *pix) { u32 walign; int ret; @@ -229,7 +239,7 @@ static int __rvin_try_format(struct rvin_dev *vin, pix->sizeimage = 0; /* Limit to source capabilities */ - ret = __rvin_try_format_source(vin, which, pix, source); + ret = __rvin_try_format_source(vin, which, pix); if (ret) return ret; @@ -238,7 +248,6 @@ static int __rvin_try_format(struct rvin_dev *vin, case V4L2_FIELD_BOTTOM: case V4L2_FIELD_ALTERNATE:
[PATCH v10 05/30] rcar-vin: move model information to own struct
When Gen3 support is added to the driver more than model ID will be different for the different SoCs. To avoid a lot of if statements in the code create a struct rvin_info to store this information. While we are at it rename the poorly chosen enum which contains the different model IDs from chip_id to model_id. Also sort the compatible string entries and make use of of_device_get_match_data() which will always work as the driver is DT only, so there's always a valid match. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 56 + drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 +- drivers/media/platform/rcar-vin/rcar-vin.h | 14 ++-- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 663309ca9c04f208..d2b27ccff690cede 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -241,21 +241,53 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) * Platform Device Driver */ +static const struct rvin_info rcar_info_h1 = { + .model = RCAR_H1, +}; + +static const struct rvin_info rcar_info_m1 = { + .model = RCAR_M1, +}; + +static const struct rvin_info rcar_info_gen2 = { + .model = RCAR_GEN2, +}; + static const struct of_device_id rvin_of_id_table[] = { - { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 }, - { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 }, - { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 }, - { }, + { + .compatible = "renesas,vin-r8a7778", + .data = &rcar_info_m1, + }, + { + .compatible = "renesas,vin-r8a7779", + .data = &rcar_info_h1, + }, + { + .compatible = "renesas,vin-r8a7790", + .data = &rcar_info_gen2, + }, + { + .compatible = "renesas,vin-r8a7791", + .data = &rcar_info_gen2, + }, + { + .compatible = "renesas,vin-r8a7793", + .data = &rcar_info_gen2, + }, + { + .compatible = "renesas,vin-r8a7794", + .data = &rcar_info_gen2, + }, + { + .compatible = "renesas,rcar-gen2-vin", + .data = &rcar_info_gen2, + }, + { /* Sentinel */ }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); static int rcar_vin_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct rvin_dev *vin; struct resource *mem; int irq, ret; @@ -264,12 +296,8 @@ static int rcar_vin_probe(struct platform_device *pdev) if (!vin) return -ENOMEM; - match = of_match_device(of_match_ptr(rvin_of_id_table), &pdev->dev); - if (!match) - return -ENODEV; - vin->dev = &pdev->dev; - vin->chip = (enum chip_id)match->data; + vin->info = of_device_get_match_data(&pdev->dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (mem == NULL) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 4a0610a6b4503501..0a035667c0b0e93f 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -266,7 +266,8 @@ static int __rvin_try_format(struct rvin_dev *vin, pix->sizeimage = max_t(u32, pix->sizeimage, rvin_format_sizeimage(pix)); - if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) { + if (vin->info->model == RCAR_M1 && + pix->pixelformat == V4L2_PIX_FMT_XBGR32) { vin_err(vin, "pixel format XBGR32 not supported on M1\n"); return -EINVAL; } diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 85cb7ec53d2b08b5..3f49d2f2d6b88471 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -29,7 +29,7 @@ /* Address alignment mask for HW buffers */ #define HW_BUFFER_MASK 0x7f -enum chip_id { +enum model_id { RCAR_H1, RCAR_M1, RCAR_GEN2, @@ -88,11 +88,19 @@ struct rvin_graph_entity { unsigned int sink_pad; }; +/** + * struct rvin_info - Information about the particular VIN implementation + * @model: VIN model + */ +struct rvin_info { + e
[PATCH v10 06/30] rcar-vin: move max width and height information to chip information
On Gen3 the max supported width and height will be different from Gen2. Move the limits to the struct rvin_info to prepare for Gen3 support. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 6 ++ drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++ drivers/media/platform/rcar-vin/rcar-vin.h | 5 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index d2b27ccff690cede..cc863e4ec9a4d4b3 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -243,14 +243,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) static const struct rvin_info rcar_info_h1 = { .model = RCAR_H1, + .max_width = 2048, + .max_height = 2048, }; static const struct rvin_info rcar_info_m1 = { .model = RCAR_M1, + .max_width = 2048, + .max_height = 2048, }; static const struct rvin_info rcar_info_gen2 = { .model = RCAR_GEN2, + .max_width = 2048, + .max_height = 2048, }; static const struct of_device_id rvin_of_id_table[] = { diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 0a035667c0b0e93f..8805d7911a761019 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -23,8 +23,6 @@ #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV -#define RVIN_MAX_WIDTH 2048 -#define RVIN_MAX_HEIGHT2048 /* - * Format Conversions @@ -258,8 +256,8 @@ static int __rvin_try_format(struct rvin_dev *vin, walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; /* Limit to VIN capabilities */ - v4l_bound_align_image(&pix->width, 2, RVIN_MAX_WIDTH, walign, - &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0); + v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, + &pix->height, 4, vin->info->max_height, 2, 0); pix->bytesperline = max_t(u32, pix->bytesperline, rvin_format_bytesperline(pix)); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 3f49d2f2d6b88471..f195d174eeacda10 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -91,9 +91,14 @@ struct rvin_graph_entity { /** * struct rvin_info - Information about the particular VIN implementation * @model: VIN model + * @max_width: max input width the VIN supports + * @max_height:max input height the VIN supports */ struct rvin_info { enum model_id model; + + unsigned int max_width; + unsigned int max_height; }; /** -- 2.16.1
[PATCH v10 04/30] rcar-vin: move subdevice handling to async callbacks
In preparation for Gen3 support move the subdevice initialization and clean up from rvin_v4l2_{register,unregister}() directly to the async callbacks. This simplifies the addition of Gen3 support as the rvin_v4l2_register() can be shared for both Gen2 and Gen3 while direct subdevice control are only used on Gen2. While moving this code drop a large comment which is copied from the framework documentation and fold rvin_mbus_supported() into its only caller. Also move the initialization and cleanup code to separate functions to increase readability. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-core.c | 108 +++- drivers/media/platform/rcar-vin/rcar-v4l2.c | 35 - 2 files changed, 74 insertions(+), 69 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 47f06acde2e698f2..663309ca9c04f208 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -46,46 +46,88 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int direction) return -EINVAL; } -static bool rvin_mbus_supported(struct rvin_graph_entity *entity) +/* The vin lock shuld be held when calling the subdevice attach and detach */ +static int rvin_digital_subdevice_attach(struct rvin_dev *vin, +struct v4l2_subdev *subdev) { - struct v4l2_subdev *sd = entity->subdev; struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; + int ret; + /* Find source and sink pad of remote subdevice */ + ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); + if (ret < 0) + return ret; + vin->digital->source_pad = ret; + + ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK); + vin->digital->sink_pad = ret < 0 ? 0 : ret; + + /* Find compatible subdevices mbus format */ + vin->digital->code = 0; code.index = 0; - code.pad = entity->source_pad; - while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) { + code.pad = vin->digital->source_pad; + while (!vin->digital->code && + !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) { code.index++; switch (code.code) { case MEDIA_BUS_FMT_YUYV8_1X16: case MEDIA_BUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_UYVY10_2X10: case MEDIA_BUS_FMT_RGB888_1X24: - entity->code = code.code; - return true; + vin->digital->code = code.code; + vin_dbg(vin, "Found media bus format for %s: %d\n", + subdev->name, vin->digital->code); + break; default: break; } } - return false; -} - -static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) -{ - struct rvin_dev *vin = notifier_to_vin(notifier); - int ret; - - /* Verify subdevices mbus format */ - if (!rvin_mbus_supported(vin->digital)) { + if (!vin->digital->code) { vin_err(vin, "Unsupported media bus format for %s\n", - vin->digital->subdev->name); + subdev->name); return -EINVAL; } - vin_dbg(vin, "Found media bus format for %s: %d\n", - vin->digital->subdev->name, vin->digital->code); + /* Read tvnorms */ + ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms); + if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) + return ret; + + /* Add the controls */ + ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16); + if (ret < 0) + return ret; + + ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler, + NULL); + if (ret < 0) { + v4l2_ctrl_handler_free(&vin->ctrl_handler); + return ret; + } + + vin->vdev.ctrl_handler = &vin->ctrl_handler; + + vin->digital->subdev = subdev; + + return 0; +} + +static void rvin_digital_subdevice_detach(struct rvin_dev *vin) +{ + rvin_v4l2_unregister(vin); + v4l2_ctrl_handler_free(&vin->ctrl_handler); + + vin->vdev.ctrl_handler = NULL; + vin->digital->subdev = NULL; +} + +static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) +{ + struct rvin_dev *vin = notifier_to_vin(notifier); + int ret; ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); if (ret < 0) { @@ -103,8 +145,10 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, struct rvin_dev *vin = notifier_to_vin(notifier); vin_dbg(vin, "unbind
[PATCH v10 07/30] rcar-vin: move functions regarding scaling
In preparation of refactoring the scaling code move the code regarding scaling to to the top of the file to avoid the need to add forward declarations. No code is changed in this commit only whole functions moved inside the same file. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-dma.c | 602 +++-- 1 file changed, 303 insertions(+), 299 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index d701b52d198243b5..a7cda3922cb74baa 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -138,305 +138,6 @@ static u32 rvin_read(struct rvin_dev *vin, u32 offset) return ioread32(vin->base + offset); } -static int rvin_setup(struct rvin_dev *vin) -{ - u32 vnmc, dmr, dmr2, interrupts; - v4l2_std_id std; - bool progressive = false, output_is_yuv = false, input_is_yuv = false; - - switch (vin->format.field) { - case V4L2_FIELD_TOP: - vnmc = VNMC_IM_ODD; - break; - case V4L2_FIELD_BOTTOM: - vnmc = VNMC_IM_EVEN; - break; - case V4L2_FIELD_INTERLACED: - /* Default to TB */ - vnmc = VNMC_IM_FULL; - /* Use BT if video standard can be read and is 60 Hz format */ - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, &std)) { - if (std & V4L2_STD_525_60) - vnmc = VNMC_IM_FULL | VNMC_FOC; - } - break; - case V4L2_FIELD_INTERLACED_TB: - vnmc = VNMC_IM_FULL; - break; - case V4L2_FIELD_INTERLACED_BT: - vnmc = VNMC_IM_FULL | VNMC_FOC; - break; - case V4L2_FIELD_ALTERNATE: - case V4L2_FIELD_NONE: - if (vin->continuous) { - vnmc = VNMC_IM_ODD_EVEN; - progressive = true; - } else { - vnmc = VNMC_IM_ODD; - } - break; - default: - vnmc = VNMC_IM_ODD; - break; - } - - /* -* Input interface -*/ - switch (vin->digital->code) { - case MEDIA_BUS_FMT_YUYV8_1X16: - /* BT.601/BT.1358 16bit YCbCr422 */ - vnmc |= VNMC_INF_YUV16; - input_is_yuv = true; - break; - case MEDIA_BUS_FMT_UYVY8_2X8: - /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? - VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; - input_is_yuv = true; - break; - case MEDIA_BUS_FMT_RGB888_1X24: - vnmc |= VNMC_INF_RGB888; - break; - case MEDIA_BUS_FMT_UYVY10_2X10: - /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? - VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; - input_is_yuv = true; - break; - default: - break; - } - - /* Enable VSYNC Field Toogle mode after one VSYNC input */ - dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); - - /* Hsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) - dmr2 |= VNDMR2_HPS; - - /* Vsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) - dmr2 |= VNDMR2_VPS; - - /* -* Output format -*/ - switch (vin->format.pixelformat) { - case V4L2_PIX_FMT_NV16: - rvin_write(vin, - ALIGN(vin->format.width * vin->format.height, 0x80), - VNUVAOF_REG); - dmr = VNDMR_DTMD_YCSEP; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_YUYV: - dmr = VNDMR_BPSM; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_UYVY: - dmr = 0; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_XRGB555: - dmr = VNDMR_DTMD_ARGB1555; - break; - case V4L2_PIX_FMT_RGB565: - dmr = 0; - break; - case V4L2_PIX_FMT_XBGR32: - /* Note: not supported on M1 */ - dmr = VNDMR_EXRGB; - break; - default: - vin_err(vin, "Invalid pixelformat (0x%x)\n", - vin->format.pixelformat); - return -EINVAL; - } - - /* Always update on field change */ - vnmc |= VNMC_VUP; - - /* If input and output use the same colorspace,
[PATCH v10 13/30] rcar-vin: add function to manipulate Gen3 chsel value
On Gen3 the CSI-2 routing is controlled by the VnCSI_IFMD register. One feature of this register is that it's only present in the VIN0 and VIN4 instances. The register in VIN0 controls the routing for VIN0-3 and the register in VIN4 controls routing for VIN4-7. To be able to control routing from a media device this function is need to control runtime PM for the subgroup master (VIN0 and VIN4). The subgroup master must be switched on before the register is manipulated, once the operation is complete it's safe to switch the master off and the new routing will still be in effect. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-dma.c | 28 drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 2f9ad1bec1c8a92f..ae286742f15a3ab5 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -16,6 +16,7 @@ #include #include +#include #include @@ -1228,3 +1229,30 @@ int rvin_dma_register(struct rvin_dev *vin, int irq) return ret; } + +/* - + * Gen3 CHSEL manipulation + */ + +void rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) +{ + u32 ifmd, vnmc; + + pm_runtime_get_sync(vin->dev); + + /* Make register writes take effect immediately */ + vnmc = rvin_read(vin, VNMC_REG); + rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG); + + ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | + VNCSI_IFMD_CSI_CHSEL(chsel); + + rvin_write(vin, ifmd, VNCSI_IFMD_REG); + + vin_dbg(vin, "Set IFMD 0x%x\n", ifmd); + + /* Restore VNMC */ + rvin_write(vin, vnmc, VNMC_REG); + + pm_runtime_put(vin->dev); +} diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 146683142e6533fa..a5dae5b5e9cb704b 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -165,4 +165,6 @@ const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); /* Cropping, composing and scaling */ void rvin_crop_scale_comp(struct rvin_dev *vin); +void rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel); + #endif -- 2.16.1
[PATCH v10 15/30] rcar-vin: break out format alignment and checking
Part of the format alignment and checking can be shared with the Gen3 format handling. Break that part out to a separate function. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 93 - 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index c606942e59b5d934..1169e6a279ecfb55 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -86,6 +86,55 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) return pix->bytesperline * pix->height; } +static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) +{ + u32 walign; + + /* If requested format is not supported fallback to the default */ + if (!rvin_format_from_pixel(pix->pixelformat)) { + vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n", + pix->pixelformat, RVIN_DEFAULT_FORMAT); + pix->pixelformat = RVIN_DEFAULT_FORMAT; + } + + /* Reject ALTERNATE until support is added to the driver */ + switch (pix->field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + break; + default: + pix->field = V4L2_FIELD_NONE; + break; + } + + /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ + walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; + + /* Limit to VIN capabilities */ + v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, + &pix->height, 4, vin->info->max_height, 2, 0); + + pix->bytesperline = max_t(u32, pix->bytesperline, + rvin_format_bytesperline(pix)); + pix->sizeimage = max_t(u32, pix->sizeimage, + rvin_format_sizeimage(pix)); + + if (vin->info->model == RCAR_M1 && + pix->pixelformat == V4L2_PIX_FMT_XBGR32) { + vin_err(vin, "pixel format XBGR32 not supported on M1\n"); + return -EINVAL; + } + + vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", + pix->width, pix->height, pix->bytesperline, pix->sizeimage); + + return 0; +} + /* - * V4L2 */ @@ -215,19 +264,12 @@ static int __rvin_try_format_source(struct rvin_dev *vin, static int __rvin_try_format(struct rvin_dev *vin, u32 which, struct v4l2_pix_format *pix) { - u32 walign; int ret; /* Keep current field if no specific one is asked for */ if (pix->field == V4L2_FIELD_ANY) pix->field = vin->format.field; - /* If requested format is not supported fallback to the default */ - if (!rvin_format_from_pixel(pix->pixelformat)) { - vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n", - pix->pixelformat, RVIN_DEFAULT_FORMAT); - pix->pixelformat = RVIN_DEFAULT_FORMAT; - } /* Always recalculate */ pix->bytesperline = 0; @@ -238,42 +280,7 @@ static int __rvin_try_format(struct rvin_dev *vin, if (ret) return ret; - /* Reject ALTERNATE until support is added to the driver */ - switch (pix->field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_NONE: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - case V4L2_FIELD_INTERLACED: - break; - default: - pix->field = V4L2_FIELD_NONE; - break; - } - - /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ - walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; - - /* Limit to VIN capabilities */ - v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, - &pix->height, 4, vin->info->max_height, 2, 0); - - pix->bytesperline = max_t(u32, pix->bytesperline, - rvin_format_bytesperline(pix)); - pix->sizeimage = max_t(u32, pix->sizeimage, - rvin_format_sizeimage(pix)); - - if (vin->info->model == RCAR_M1 && - pix->pixelformat == V4L2_PIX_FMT_XBGR32) { - vin_err(vin, "pixel format XBGR32 not supported on M1\n"); - return -EINVAL; - } - - vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", - pix->width, pix->height, pix->bytesperline, pix->sizeimage); - - return 0; + return rvin_format_align(vin, pix); } static int rvin_querycap(struct fil
[PATCH v10 26/30] rcar-vin: add link notify for Gen3
Add the ability to process media device link change request. Link enabling is a bit complicated on Gen3, whether or not it's possible to enable a link depends on what other links already are enabled. On Gen3 the 8 VINs are split into two subgroup's (VIN0-3 and VIN4-7) and from a routing perspective these two groups are independent of each other. Each subgroup's routing is controlled by the subgroup VIN master instance (VIN0 and VIN4). There are a limited number of possible route setups available for each subgroup and the configuration of each setup is dictated by the hardware. On H3 for example there are 6 possible route setups for each subgroup to choose from. This leads to the media device link notification code being rather large since it will find the best routing configuration to try and accommodate as many links as possible. When it's not possible to enable a new link due to hardware constrains the link_notifier callback will return -EMLINK. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-core.c | 129 1 file changed, 129 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index f08277a0dc11f477..7ceff0de40078580 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -24,6 +24,7 @@ #include #include +#include #include "rcar-vin.h" @@ -44,6 +45,133 @@ */ #define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4) +/* - + * Media Controller link notification + */ + +/* group lock should be held when calling this function */ +static int rvin_group_entity_to_csi_id(struct rvin_group *group, + struct media_entity *entity) +{ + struct v4l2_subdev *sd; + int i; + + if (!is_media_entity_v4l2_subdev(entity)) + return -ENODEV; + + sd = media_entity_to_v4l2_subdev(entity); + + for (i = 0; i < RVIN_CSI_MAX; i++) + if (group->csi[i].subdev == sd) + return i; + + return -ENODEV; +} + +static unsigned int rvin_group_get_mask(struct rvin_dev *vin, + enum rvin_csi_id csi_id, + unsigned char chan) +{ + const struct rvin_group_route *route; + unsigned int mask = 0; + + for (route = vin->info->routes; route->mask; route++) { + if (route->vin == vin->id && + route->csi == csi_id && + route->chan == chan) { + vin_dbg(vin, "Adding route: vin: %d csi: %d chan: %d\n", + route->vin, route->csi, route->chan); + mask |= route->mask; + } + } + + return mask; +} + +static int rvin_group_link_notify(struct media_link *link, u32 flags, + unsigned int notification) +{ + struct rvin_group *group = container_of(link->graph_obj.mdev, + struct rvin_group, mdev); + unsigned int i, master_id, chan, mask_new, mask = ~0; + struct media_entity *entity; + struct video_device *vdev; + struct media_pad *csi_pad; + struct rvin_dev *vin = NULL; + int csi_id, ret; + + ret = v4l2_pipeline_link_notify(link, flags, notification); + if (ret) + return ret; + + /* Only care about link enablement for VIN nodes */ + if (!(flags & MEDIA_LNK_FL_ENABLED) || + !is_media_entity_v4l2_video_device(link->sink->entity)) + return 0; + + /* If any entity are in use don't allow link changes */ + media_device_for_each_entity(entity, &group->mdev) + if (entity->use_count) + return -EBUSY; + + mutex_lock(&group->lock); + + /* Find VIN and its master for which the link */ + entity = link->sink->entity; + vdev = media_entity_to_video_device(entity); + for (i = 0; i < RCAR_VIN_NUM; i++) { + if (group->vin[i] && &group->vin[i]->vdev == vdev) { + vin = group->vin[i]; + master_id = rvin_group_id_to_master(vin->id); + break; + } + } + if (WARN_ON(!vin || !group->vin[master_id])) { + ret = -ENODEV; + goto out; + } + + /* Build a mask for already enabled links */ + for (i = master_id; i < master_id + 4; i++) { + if (!group->vin[i]) + continue; + + /* Get remote CSI-2, if any */ + csi_pad = media_entity_remote_pad( + &group->vin[i]->vdev.entity.pads[0]); + if (!csi_pad) + continue; + + csi_id = rvin_group_e
[PATCH v10 22/30] rcar-vin: add group allocator functions
In media controller mode all VIN instances needs to be part of the same media graph. There is also a need for each VIN instance to know about and in some cases be able to communicate with other VIN instances. Add an allocator framework where the first VIN instance to be probed creates a shared data structure and registers a media device. Consecutive VINs insert themself into the global group. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-core.c | 177 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 31 + 2 files changed, 206 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 0c6960756c33f86c..4a64df5019ce45f7 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -20,12 +20,177 @@ #include #include #include +#include #include #include #include "rcar-vin.h" +/* - + * Gen3 CSI2 Group Allocator + */ + +/* FIXME: This should if we find a system that supports more + * then one group for the whole system be replaced with a linked + * list of groups. And eventually all of this should be replaced + * with a global device allocator API. + * + * But for now this works as on all supported systems there will + * be only one group for all instances. + */ + +static DEFINE_MUTEX(rvin_group_lock); +static struct rvin_group *rvin_group_data; + +static void rvin_group_cleanup(struct rvin_group *group) +{ + media_device_unregister(&group->mdev); + media_device_cleanup(&group->mdev); + mutex_destroy(&group->lock); +} + +static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin) +{ + struct media_device *mdev = &group->mdev; + const struct of_device_id *match; + struct device_node *np; + int ret; + + mutex_init(&group->lock); + + /* Count number of VINs in the system */ + group->count = 0; + for_each_matching_node(np, vin->dev->driver->of_match_table) + if (of_device_is_available(np)) + group->count++; + + vin_dbg(vin, "found %u enabled VIN's in DT", group->count); + + mdev->dev = vin->dev; + + match = of_match_node(vin->dev->driver->of_match_table, + vin->dev->of_node); + + strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); + strlcpy(mdev->model, match->compatible, sizeof(mdev->model)); + snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", +dev_name(mdev->dev)); + + media_device_init(mdev); + + ret = media_device_register(&group->mdev); + if (ret) + rvin_group_cleanup(group); + + return ret; +} + +static void rvin_group_release(struct kref *kref) +{ + struct rvin_group *group = + container_of(kref, struct rvin_group, refcount); + + mutex_lock(&rvin_group_lock); + + rvin_group_data = NULL; + + rvin_group_cleanup(group); + + kfree(group); + + mutex_unlock(&rvin_group_lock); +} + +static int rvin_group_get(struct rvin_dev *vin) +{ + struct rvin_group *group; + u32 id; + int ret; + + /* Make sure VIN id is present and sane */ + ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id); + if (ret) { + vin_err(vin, "%pOF: No renesas,id property found\n", + vin->dev->of_node); + return -EINVAL; + } + + if (id >= RCAR_VIN_NUM) { + vin_err(vin, "%pOF: Invalid renesas,id '%u'\n", + vin->dev->of_node, id); + return -EINVAL; + } + + /* Join or create a VIN group */ + mutex_lock(&rvin_group_lock); + if (rvin_group_data) { + group = rvin_group_data; + kref_get(&group->refcount); + } else { + group = kzalloc(sizeof(*group), GFP_KERNEL); + if (!group) { + ret = -ENOMEM; + goto err_group; + } + + ret = rvin_group_init(group, vin); + if (ret) { + kfree(group); + vin_err(vin, "Failed to initialize group\n"); + goto err_group; + } + + kref_init(&group->refcount); + + rvin_group_data = group; + } + mutex_unlock(&rvin_group_lock); + + /* Add VIN to group */ + mutex_lock(&group->lock); + + if (group->vin[id]) { + vin_err(vin, "Duplicate renesas,id property value %u\n", id); + ret = -EINVAL; + goto err_vin; + } + + group->vin[id] = vin; + + vin->id = id; + vin->group = group; + vin->v4l2_dev.mdev = &group->mdev;
[PATCH v10 25/30] rcar-vin: parse Gen3 OF and setup media graph
The parsing and registering CSI-2 subdevices with the v4l2 async framework is a collaborative effort shared between the VIN instances which are part of the group. When the last VIN in the group is probed it asks all other VINs to parse its share of OF and record the async subdevices it finds in the notifier belonging to the last probed VIN. Once all CSI-2 subdevices in this notifier are bound proceed to register all VIN video devices of the group and crate media device links between all CSI-2 and VIN entities according to the SoC specific routing configuration. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-core.c | 250 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 12 +- 2 files changed, 258 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 4a64df5019ce45f7..f08277a0dc11f477 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -27,6 +27,23 @@ #include "rcar-vin.h" +/* + * The companion CSI-2 receiver driver (rcar-csi2) is known + * and we know it have one source pad (pad 0) and four sink + * pads (pad 1-4). So to translate a pad on the remote + * CSI-2 receiver to/from the VIN internal channel number simply + * subtract/add or one from the pad/chan number. + */ +#define rvin_group_csi_pad_to_chan(pad) ((pad) - 1) +#define rvin_group_csi_chan_to_pad(chan) ((chan) + 1) + +/* + * Not all VINs are created equal, master VINs control the + * routing for other VIN's. We can figure out which VIN is + * master by looking at a VINs id + */ +#define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4) + /* - * Gen3 CSI2 Group Allocator */ @@ -77,6 +94,8 @@ static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin) snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", dev_name(mdev->dev)); + group->notifier = NULL; + media_device_init(mdev); ret = media_device_register(&group->mdev); @@ -406,6 +425,218 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) return 0; } +/* - + * Group async notifier + */ + +static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) +{ + struct rvin_dev *vin = notifier_to_vin(notifier); + const struct rvin_group_route *route; + unsigned int i; + int ret; + + ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); + if (ret) { + vin_err(vin, "Failed to register subdev nodes\n"); + return ret; + } + + /* Register all video nodes for the group */ + for (i = 0; i < RCAR_VIN_NUM; i++) { + if (vin->group->vin[i]) { + ret = rvin_v4l2_register(vin->group->vin[i]); + if (ret) + return ret; + } + } + + /* Create all media device links between VINs and CSI-2's */ + mutex_lock(&vin->group->lock); + for (route = vin->info->routes; route->mask; route++) { + struct media_pad *source_pad, *sink_pad; + struct media_entity *source, *sink; + unsigned int source_idx; + + /* Check that VIN is part of the group */ + if (!vin->group->vin[route->vin]) + continue; + + /* Check that VIN' master is part of the group */ + if (!vin->group->vin[rvin_group_id_to_master(route->vin)]) + continue; + + /* Check that CSI-2 is part of the group */ + if (!vin->group->csi[route->csi].subdev) + continue; + + source = &vin->group->csi[route->csi].subdev->entity; + source_idx = rvin_group_csi_chan_to_pad(route->chan); + source_pad = &source->pads[source_idx]; + + sink = &vin->group->vin[route->vin]->vdev.entity; + sink_pad = &sink->pads[0]; + + /* Skip if link already exists */ + if (media_entity_find_link(source_pad, sink_pad)) + continue; + + ret = media_create_pad_link(source, source_idx, sink, 0, 0); + if (ret) { + vin_err(vin, "Error adding link from %s to %s\n", + source->name, sink->name); + break; + } + } + mutex_unlock(&vin->group->lock); + + return ret; +} + +static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, +struct v4l2_subdev *subdev, +struct v4l2_async_subdev *asd) +{ + struct rvin_dev *vin = notifie
[PATCH v10 17/30] rcar-vin: update pixelformat check for M1
If the pixelformat is not supported it should not fail but be set to something that works. While we are at it move the check together with other pixelformat checks of this function. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index bca6e204a574772f..841d62ca27e026d7 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -97,6 +97,10 @@ static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) pix->pixelformat = RVIN_DEFAULT_FORMAT; } + if (vin->info->model == RCAR_M1 && + pix->pixelformat == V4L2_PIX_FMT_XBGR32) + pix->pixelformat = RVIN_DEFAULT_FORMAT; + /* Reject ALTERNATE until support is added to the driver */ switch (pix->field) { case V4L2_FIELD_TOP: @@ -121,12 +125,6 @@ static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) pix->bytesperline = rvin_format_bytesperline(pix); pix->sizeimage = rvin_format_sizeimage(pix); - if (vin->info->model == RCAR_M1 && - pix->pixelformat == V4L2_PIX_FMT_XBGR32) { - vin_err(vin, "pixel format XBGR32 not supported on M1\n"); - return -EINVAL; - } - vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", pix->width, pix->height, pix->bytesperline, pix->sizeimage); -- 2.16.1
[PATCH v10 24/30] rcar-vin: add chsel information to rvin_info
Each Gen3 SoC has a limited set of predefined routing possibilities for which CSI-2 device and virtual channel can be routed to which VIN instance. Prepare to store this information in the struct rvin_info. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-vin.h | 30 ++ 1 file changed, 30 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 903d8fb8426a7860..ca2c2a23cef8506c 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -43,6 +43,14 @@ enum model_id { RCAR_GEN3, }; +enum rvin_csi_id { + RVIN_CSI20, + RVIN_CSI21, + RVIN_CSI40, + RVIN_CSI41, + RVIN_CSI_MAX, +}; + /** * STOPPED - No operation in progress * RUNNING - Operation in progress have buffers @@ -81,12 +89,33 @@ struct rvin_graph_entity { unsigned int sink_pad; }; +/** struct rvin_group_route - Map a CSI-2 receiver and channel to a CHSEL + * @vin: Which VIN the CSI-2 and VC describes + * @csi: VIN internal number for CSI-2 device + * @chan: Output channel of the CSI-2 receiver. Each R-Car CSI-2 + * receiver has four output channels facing the VIN + * devices, each channel can carry one CSI-2 Virtual + * Channel (VC) and there are no correlation between + * output channel number and CSI-2 VC. It's up to the + * CSI-2 receiver driver to configure which VC is + * outputted on which channel, the VIN devices only + * cares about output channels. + * @mask: Bitmask of chsel values which accommodates route + */ +struct rvin_group_route { + unsigned int vin; + enum rvin_csi_id csi; + unsigned char chan; + unsigned int mask; +}; + /** * struct rvin_info - Information about the particular VIN implementation * @model: VIN model * @use_mc:use media controller instead of controlling subdevice * @max_width: max input width the VIN supports * @max_height:max input height the VIN supports + * @routes:routing table VIN <-> CSI-2 for the chsel values */ struct rvin_info { enum model_id model; @@ -94,6 +123,7 @@ struct rvin_info { unsigned int max_width; unsigned int max_height; + const struct rvin_group_route *routes; }; /** -- 2.16.1
[PATCH v10 27/30] rcar-vin: extend {start,stop}_streaming to work with media controller
The procedure to start or stop streaming using the non-MC single subdevice and the MC graph and multiple subdevices are quite different. Create a new function to abstract which method is used based on which mode the driver is running in and add logic to start the MC graph. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-dma.c | 123 +++-- 1 file changed, 116 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 811d8f8638d21200..6784e7eb3d96e1c0 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1087,15 +1087,126 @@ static void rvin_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(&vin->qlock, flags); } +static int rvin_set_stream(struct rvin_dev *vin, int on) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct media_pipeline *pipe; + struct media_device *mdev; + struct v4l2_subdev *sd; + struct media_pad *pad; + int ret; + + /* No media controller used, simply pass operation to subdevice */ + if (!vin->info->use_mc) { + ret = v4l2_subdev_call(vin->digital->subdev, video, s_stream, + on); + + return ret == -ENOIOCTLCMD ? 0 : ret; + } + + pad = media_entity_remote_pad(&vin->pad); + if (!pad) + return -EPIPE; + + sd = media_entity_to_v4l2_subdev(pad->entity); + + if (!on) { + media_pipeline_stop(&vin->vdev.entity); + return v4l2_subdev_call(sd, video, s_stream, 0); + } + + fmt.pad = pad->index; + if (v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt)) + return -EPIPE; + + switch (fmt.format.code) { + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY10_2X10: + case MEDIA_BUS_FMT_RGB888_1X24: + vin->code = fmt.format.code; + break; + default: + return -EPIPE; + } + + switch (fmt.format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + /* Supported natively */ + break; + case V4L2_FIELD_ALTERNATE: + switch (vin->format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + break; + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + /* Use VIN hardware to combine the two fields */ + fmt.format.height *= 2; + break; + default: + return -EPIPE; + } + break; + default: + return -EPIPE; + } + + if (fmt.format.width != vin->format.width || + fmt.format.height != vin->format.height || + fmt.format.code != vin->code) + return -EPIPE; + + mdev = vin->vdev.entity.graph_obj.mdev; + + /* +* The graph lock needs to be taken to protect concurrent +* starts of multiple VIN instances as they might share +* a common subdevice down the line and then should use +* the same pipe. +*/ + mutex_lock(&mdev->graph_mutex); + pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe; + ret = __media_pipeline_start(&vin->vdev.entity, pipe); + mutex_unlock(&mdev->graph_mutex); + if (ret) + return ret; + + ret = v4l2_subdev_call(sd, video, s_stream, 1); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret) + media_pipeline_stop(&vin->vdev.entity); + + return ret; +} + static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) { struct rvin_dev *vin = vb2_get_drv_priv(vq); - struct v4l2_subdev *sd; unsigned long flags; int ret; - sd = vin_to_source(vin); - v4l2_subdev_call(sd, video, s_stream, 1); + ret = rvin_set_stream(vin, 1); + if (ret) { + spin_lock_irqsave(&vin->qlock, flags); + return_all_buffers(vin, VB2_BUF_STATE_QUEUED); + spin_unlock_irqrestore(&vin->qlock, flags); + return ret; + } spin_lock_irqsave(&vin->qlock, flags); @@ -1104,7 +1215,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
[PATCH v10 29/30] rcar-vin: enable support for r8a7796
Add the SoC specific information for Renesas r8a7796. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-core.c | 44 + 1 file changed, 44 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 43d2fa83875817f0..2305fedd293db241 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -914,6 +914,46 @@ static const struct rvin_info rcar_info_r8a7795es1 = { .routes = rcar_info_r8a7795es1_routes, }; +static const struct rvin_group_route rcar_info_r8a7796_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 0, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { .vin = 4, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 4, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 5, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 5, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 6, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 6, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 7, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) }, + { .vin = 7, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a7796 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = rcar_info_r8a7796_routes, +}; + static const struct of_device_id rvin_of_id_table[] = { { .compatible = "renesas,vin-r8a7778", @@ -947,6 +987,10 @@ static const struct of_device_id rvin_of_id_table[] = { .compatible = "renesas,vin-r8a7795", .data = &rcar_info_r8a7795, }, + { + .compatible = "renesas,vin-r8a7796", + .data = &rcar_info_r8a7796, + }, { /* Sentinel */ }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); -- 2.16.1
[PATCH v10 23/30] rcar-vin: change name of video device
The rcar-vin driver needs to be part of a media controller to support Gen3. Give each VIN instance a unique name so it can be referenced from userspace. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 292e1f22a4be36c7..3ac6cdcb18ce4a21 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -1012,7 +1012,7 @@ int rvin_v4l2_register(struct rvin_dev *vin) /* video node */ vdev->v4l2_dev = &vin->v4l2_dev; vdev->queue = &vin->queue; - strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name)); + snprintf(vdev->name, sizeof(vdev->name), "VIN%u output", vin->id); vdev->release = video_device_release_empty; vdev->lock = &vin->lock; vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | -- 2.16.1
[PATCH v10 28/30] rcar-vin: enable support for r8a7795
Add the SoC specific information for Renesas r8a7795 ES1.x and ES2.0. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/Kconfig | 2 +- drivers/media/platform/rcar-vin/rcar-core.c | 120 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig index af4c98b44d2e22cb..8fa7ee468c63afb9 100644 --- a/drivers/media/platform/rcar-vin/Kconfig +++ b/drivers/media/platform/rcar-vin/Kconfig @@ -6,7 +6,7 @@ config VIDEO_RCAR_VIN select V4L2_FWNODE ---help--- Support for Renesas R-Car Video Input (VIN) driver. - Supports R-Car Gen2 SoCs. + Supports R-Car Gen2 and Gen3 SoCs. To compile this driver as a module, choose M here: the module will be called rcar-vin. diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 7ceff0de40078580..43d2fa83875817f0 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -815,6 +816,104 @@ static const struct rvin_info rcar_info_gen2 = { .max_height = 2048, }; +static const struct rvin_group_route rcar_info_r8a7795_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 0, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 0, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(1) | BIT(3) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(0) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) | BIT(2) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { .vin = 4, .csi = RVIN_CSI41, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 4, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 4, .csi = RVIN_CSI41, .chan = 1, .mask = BIT(2) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 5, .csi = RVIN_CSI41, .chan = 1, .mask = BIT(1) | BIT(3) }, + { .vin = 5, .csi = RVIN_CSI41, .chan = 0, .mask = BIT(2) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(0) }, + { .vin = 6, .csi = RVIN_CSI41, .chan = 0, .mask = BIT(1) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 6, .csi = RVIN_CSI41, .chan = 2, .mask = BIT(3) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 7, .csi = RVIN_CSI41, .chan = 1, .mask = BIT(0) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) | BIT(2) }, + { .vin = 7, .csi = RVIN_CSI41, .chan = 3, .mask = BIT(3) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a7795 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = rcar_info_r8a7795_routes, +}; + +static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 0, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 0, .csi = RVIN_CSI21, .chan = 0, .mask = BIT(2) | BIT(5) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 1, .csi = RVIN_CSI21, .chan = 0, .mask = BIT(1) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 1, .csi = RVIN_CSI21, .chan = 1, .mask = BIT(5) }, + { .vin = 2, .csi = RVIN_CSI21, .chan = 0, .mask = BIT(0) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 2, .csi = RVIN_CSI21, .chan = 2, .mask = BIT(5) }, + { .
[PATCH v10 30/30] rcar-vin: enable support for r8a77970
Add the SoC specific information for Renesas r8a77970. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-core.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 2305fedd293db241..496b7d2189d73d37 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -954,6 +954,25 @@ static const struct rvin_info rcar_info_r8a7796 = { .routes = rcar_info_r8a7796_routes, }; +static const struct rvin_group_route _rcar_info_r8a77970_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a77970 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = _rcar_info_r8a77970_routes, +}; + static const struct of_device_id rvin_of_id_table[] = { { .compatible = "renesas,vin-r8a7778", @@ -991,6 +1010,10 @@ static const struct of_device_id rvin_of_id_table[] = { .compatible = "renesas,vin-r8a7796", .data = &rcar_info_r8a7796, }, + { + .compatible = "renesas,vin-r8a77970", + .data = &rcar_info_r8a77970, + }, { /* Sentinel */ }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); -- 2.16.1
[PATCH v10 16/30] rcar-vin: update bytesperline and sizeimage calculation
Remove over complicated logic to calculate the value for bytesperline and sizeimage that was carried over from the soc_camera port. Update the calculations to match how other drivers are doing it. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 11 ++- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 1169e6a279ecfb55..bca6e204a574772f 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -118,10 +118,8 @@ static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, &pix->height, 4, vin->info->max_height, 2, 0); - pix->bytesperline = max_t(u32, pix->bytesperline, - rvin_format_bytesperline(pix)); - pix->sizeimage = max_t(u32, pix->sizeimage, - rvin_format_sizeimage(pix)); + pix->bytesperline = rvin_format_bytesperline(pix); + pix->sizeimage = rvin_format_sizeimage(pix); if (vin->info->model == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) { @@ -270,11 +268,6 @@ static int __rvin_try_format(struct rvin_dev *vin, if (pix->field == V4L2_FIELD_ANY) pix->field = vin->format.field; - - /* Always recalculate */ - pix->bytesperline = 0; - pix->sizeimage = 0; - /* Limit to source capabilities */ ret = __rvin_try_format_source(vin, which, pix); if (ret) -- 2.16.1
[PATCH v10 21/30] rcar-vin: prepare for media controller mode initialization
Prepare for media controller by calling a different initialization then for when running in device centric mode. Add trivial configuration of the mbus and creation of the media pad for the video device entity. While we are at it clearly mark the digital device centric notifier functions with a comment. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 20 ++-- drivers/media/platform/rcar-vin/rcar-vin.h | 4 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 64034c96f384b3ed..0c6960756c33f86c 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -46,6 +46,10 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int direction) return -EINVAL; } +/* - + * Digital async notifier + */ + /* The vin lock shuld be held when calling the subdevice attach and detach */ static int rvin_digital_subdevice_attach(struct rvin_dev *vin, struct v4l2_subdev *subdev) @@ -237,6 +241,16 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) return 0; } +static int rvin_mc_init(struct rvin_dev *vin) +{ + /* All our sources are CSI-2 */ + vin->mbus_cfg.type = V4L2_MBUS_CSI2; + vin->mbus_cfg.flags = 0; + + vin->pad.flags = MEDIA_PAD_FL_SINK; + return media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad); +} + /* - * Platform Device Driver */ @@ -325,8 +339,10 @@ static int rcar_vin_probe(struct platform_device *pdev) return ret; platform_set_drvdata(pdev, vin); - - ret = rvin_digital_graph_init(vin); + if (vin->info->use_mc) + ret = rvin_mc_init(vin); + else + ret = rvin_digital_graph_init(vin); if (ret < 0) goto error; diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 64476bc5c8abc6d0..4caef7193db09c5b 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -101,6 +101,8 @@ struct rvin_info { * @notifier: V4L2 asynchronous subdevs notifier * @digital: entity in the DT for local digital subdevice * + * @pad: media pad for the video device entity + * * @lock: protects @queue * @queue: vb2 buffers queue * @@ -130,6 +132,8 @@ struct rvin_dev { struct v4l2_async_notifier notifier; struct rvin_graph_entity *digital; + struct media_pad pad; + struct mutex lock; struct vb2_queue queue; -- 2.16.1
[PATCH v10 20/30] rcar-vin: use different v4l2 operations in media controller mode
When the driver runs in media controller mode it should not directly control the subdevice instead userspace will be responsible for configuring the pipeline. To be able to run in this mode a different set of v4l2 operations needs to be used. Add a new set of v4l2 operations to support operation without directly interacting with the source subdevice. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 3 +- drivers/media/platform/rcar-vin/rcar-v4l2.c | 155 +++- 2 files changed, 154 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index ae286742f15a3ab5..811d8f8638d21200 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -628,7 +628,8 @@ static int rvin_setup(struct rvin_dev *vin) /* Default to TB */ vnmc = VNMC_IM_FULL; /* Use BT if video standard can be read and is 60 Hz format */ - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, &std)) { + if (!vin->info->use_mc && + !v4l2_subdev_call(vin_to_source(vin), video, g_std, &std)) { if (std & V4L2_STD_525_60) vnmc = VNMC_IM_FULL | VNMC_FOC; } diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index f69ae76b3fda50c7..292e1f22a4be36c7 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -18,11 +18,14 @@ #include #include +#include #include #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV +#define RVIN_DEFAULT_WIDTH 800 +#define RVIN_DEFAULT_HEIGHT600 #define RVIN_DEFAULT_FIELD V4L2_FIELD_NONE #define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB @@ -698,6 +701,83 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; +/* - + * V4L2 Media Controller + */ + +static int __rvin_mc_try_format(struct rvin_dev *vin, + struct v4l2_pix_format *pix) +{ + if (pix->field == V4L2_FIELD_ANY) + pix->field = RVIN_DEFAULT_FIELD; + + return rvin_format_align(vin, pix); +} + +static int rvin_mc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct rvin_dev *vin = video_drvdata(file); + + return __rvin_mc_try_format(vin, &f->fmt.pix); +} + +static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv, +struct v4l2_format *f) +{ + struct rvin_dev *vin = video_drvdata(file); + int ret; + + if (vb2_is_busy(&vin->queue)) + return -EBUSY; + + ret = __rvin_mc_try_format(vin, &f->fmt.pix); + if (ret) + return ret; + + vin->format = f->fmt.pix; + + return 0; +} + +static int rvin_mc_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + if (i->index != 0) + return -EINVAL; + + i->type = V4L2_INPUT_TYPE_CAMERA; + strlcpy(i->name, "Camera", sizeof(i->name)); + + return 0; +} + +static const struct v4l2_ioctl_ops rvin_mc_ioctl_ops = { + .vidioc_querycap= rvin_querycap, + .vidioc_try_fmt_vid_cap = rvin_mc_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = rvin_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = rvin_mc_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap= rvin_enum_fmt_vid_cap, + + .vidioc_enum_input = rvin_mc_enum_input, + .vidioc_g_input = rvin_g_input, + .vidioc_s_input = rvin_s_input, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf= vb2_ioctl_querybuf, + .vidioc_qbuf= vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_streamon= vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = rvin_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + /* - * File Operations */ @@ -841,6 +921,60 @@ static const struct v4l2_file_operations rvin_fops = { .read = vb2_f
[PATCH v10 18/30] rcar-vin: add check for colorspace
Add a check to ensure the colorspace from user-space is good. On Gen2 it works without this change as the sensor sets the colorspace but on Gen3 this can fail if the colorspace provided by the user is not good. The values to check for comes from v4l2-compliance sources which is the tool that found this error. If this check is not preformed v4l2-compliance fails when it tests colorspace. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 841d62ca27e026d7..6403650aff22a2ed 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -23,6 +23,7 @@ #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV +#define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB /* - * Format Conversions @@ -115,6 +116,10 @@ static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) break; } + /* Check that colorspace is reasonable */ + if (!pix->colorspace || pix->colorspace >= 0xff) + pix->colorspace = RVIN_DEFAULT_COLORSPACE; + /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; -- 2.16.1
[PATCH v10 19/30] rcar-vin: set a default field to fallback on
If the field is not supported by the driver it should not try to keep the current field. Instead it should set it to a default fallback. Since trying a format should always result in the same state regardless of the current state of the device. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 6403650aff22a2ed..f69ae76b3fda50c7 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -23,6 +23,7 @@ #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV +#define RVIN_DEFAULT_FIELD V4L2_FIELD_NONE #define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB /* - @@ -171,7 +172,7 @@ static int rvin_get_source_format(struct rvin_dev *vin, fmt.format.height *= 2; break; default: - vin->format.field = V4L2_FIELD_NONE; + vin->format.field = RVIN_DEFAULT_FIELD; break; } @@ -267,9 +268,8 @@ static int __rvin_try_format(struct rvin_dev *vin, { int ret; - /* Keep current field if no specific one is asked for */ if (pix->field == V4L2_FIELD_ANY) - pix->field = vin->format.field; + pix->field = RVIN_DEFAULT_FIELD; /* Limit to source capabilities */ ret = __rvin_try_format_source(vin, which, pix); -- 2.16.1
[PATCH v10 14/30] rcar-vin: add flag to switch to media controller mode
On Gen3 a media controller API needs to be used to allow userspace to configure the subdevices in the pipeline instead of directly controlling a single source subdevice, which is and will continue to be the mode of operation on Gen2. Prepare for these two modes of operation by adding a flag to struct rvin_info which will control which mode to use. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 6 +- drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index ce1c90405c6002eb..64034c96f384b3ed 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -243,18 +243,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) static const struct rvin_info rcar_info_h1 = { .model = RCAR_H1, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; static const struct rvin_info rcar_info_m1 = { .model = RCAR_M1, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; static const struct rvin_info rcar_info_gen2 = { .model = RCAR_GEN2, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; @@ -349,7 +352,8 @@ static int rcar_vin_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(&vin->notifier); v4l2_async_notifier_cleanup(&vin->notifier); - v4l2_ctrl_handler_free(&vin->ctrl_handler); + if (!vin->info->use_mc) + v4l2_ctrl_handler_free(&vin->ctrl_handler); rvin_dma_unregister(vin); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index a5dae5b5e9cb704b..64476bc5c8abc6d0 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -77,11 +77,13 @@ struct rvin_graph_entity { /** * struct rvin_info - Information about the particular VIN implementation * @model: VIN model + * @use_mc:use media controller instead of controlling subdevice * @max_width: max input width the VIN supports * @max_height:max input height the VIN supports */ struct rvin_info { enum model_id model; + bool use_mc; unsigned int max_width; unsigned int max_height; -- 2.16.1
[PATCH v10 11/30] rcar-vin: move media bus configuration to struct rvin_info
Bus configuration will once the driver is extended to support Gen3 contain information not specific to only the directly connected parallel subdevice. Move it to struct rvin_dev to show it's not always coupled to the parallel subdevice. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 18 +- drivers/media/platform/rcar-vin/rcar-dma.c | 11 ++- drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +- drivers/media/platform/rcar-vin/rcar-vin.h | 9 - 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index cc863e4ec9a4d4b3..ce1c90405c6002eb 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -65,10 +65,10 @@ static int rvin_digital_subdevice_attach(struct rvin_dev *vin, vin->digital->sink_pad = ret < 0 ? 0 : ret; /* Find compatible subdevices mbus format */ - vin->digital->code = 0; + vin->code = 0; code.index = 0; code.pad = vin->digital->source_pad; - while (!vin->digital->code && + while (!vin->code && !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) { code.index++; switch (code.code) { @@ -76,16 +76,16 @@ static int rvin_digital_subdevice_attach(struct rvin_dev *vin, case MEDIA_BUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_UYVY10_2X10: case MEDIA_BUS_FMT_RGB888_1X24: - vin->digital->code = code.code; + vin->code = code.code; vin_dbg(vin, "Found media bus format for %s: %d\n", - subdev->name, vin->digital->code); + subdev->name, vin->code); break; default: break; } } - if (!vin->digital->code) { + if (!vin->code) { vin_err(vin, "Unsupported media bus format for %s\n", subdev->name); return -EINVAL; @@ -190,16 +190,16 @@ static int rvin_digital_parse_v4l2(struct device *dev, if (vep->base.port || vep->base.id) return -ENOTCONN; - rvge->mbus_cfg.type = vep->bus_type; + vin->mbus_cfg.type = vep->bus_type; - switch (rvge->mbus_cfg.type) { + switch (vin->mbus_cfg.type) { case V4L2_MBUS_PARALLEL: vin_dbg(vin, "Found PARALLEL media bus\n"); - rvge->mbus_cfg.flags = vep->bus.parallel.flags; + vin->mbus_cfg.flags = vep->bus.parallel.flags; break; case V4L2_MBUS_BT656: vin_dbg(vin, "Found BT656 media bus\n"); - rvge->mbus_cfg.flags = 0; + vin->mbus_cfg.flags = 0; break; default: vin_err(vin, "Unknown media bus type\n"); diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index c8831e189d362c8b..561500f65cfa2e74 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -633,7 +633,7 @@ static int rvin_setup(struct rvin_dev *vin) /* * Input interface */ - switch (vin->digital->code) { + switch (vin->code) { case MEDIA_BUS_FMT_YUYV8_1X16: /* BT.601/BT.1358 16bit YCbCr422 */ vnmc |= VNMC_INF_YUV16; @@ -641,7 +641,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY8_2X8: /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; input_is_yuv = true; break; @@ -650,7 +650,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY10_2X10: /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; input_is_yuv = true; break; @@ -662,11 +662,11 @@ static int rvin_setup(struct rvin_dev *vin) dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); /* Hsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) + if (!(vin->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) dmr2 |= VNDMR2_HPS; /* Vsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) + i
[PATCH v10 12/30] rcar-vin: enable Gen3 hardware configuration
Add the register needed to work with Gen3 hardware. This patch adds the logic for how to work with the Gen3 hardware. More work is required to enable the subdevice structure needed to configure capturing. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-dma.c | 94 -- drivers/media/platform/rcar-vin/rcar-vin.h | 1 + 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 561500f65cfa2e74..2f9ad1bec1c8a92f 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -33,21 +33,23 @@ #define VNELPRC_REG0x10/* Video n End Line Pre-Clip Register */ #define VNSPPRC_REG0x14/* Video n Start Pixel Pre-Clip Register */ #define VNEPPRC_REG0x18/* Video n End Pixel Pre-Clip Register */ -#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */ -#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */ -#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */ -#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */ #define VNIS_REG 0x2C/* Video n Image Stride Register */ #define VNMB_REG(m)(0x30 + ((m) << 2)) /* Video n Memory Base m Register */ #define VNIE_REG 0x40/* Video n Interrupt Enable Register */ #define VNINTS_REG 0x44/* Video n Interrupt Status Register */ #define VNSI_REG 0x48/* Video n Scanline Interrupt Register */ #define VNMTC_REG 0x4C/* Video n Memory Transfer Control Register */ -#define VNYS_REG 0x50/* Video n Y Scale Register */ -#define VNXS_REG 0x54/* Video n X Scale Register */ #define VNDMR_REG 0x58/* Video n Data Mode Register */ #define VNDMR2_REG 0x5C/* Video n Data Mode Register 2 */ #define VNUVAOF_REG0x60/* Video n UV Address Offset Register */ + +/* Register offsets specific for Gen2 */ +#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */ +#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */ +#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */ +#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */ +#define VNYS_REG 0x50/* Video n Y Scale Register */ +#define VNXS_REG 0x54/* Video n X Scale Register */ #define VNC1A_REG 0x80/* Video n Coefficient Set C1A Register */ #define VNC1B_REG 0x84/* Video n Coefficient Set C1B Register */ #define VNC1C_REG 0x88/* Video n Coefficient Set C1C Register */ @@ -73,9 +75,13 @@ #define VNC8B_REG 0xF4/* Video n Coefficient Set C8B Register */ #define VNC8C_REG 0xF8/* Video n Coefficient Set C8C Register */ +/* Register offsets specific for Gen3 */ +#define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */ /* Register bit fields for R-Car VIN */ /* Video n Main Control Register bits */ +#define VNMC_DPINE (1 << 27) /* Gen3 specific */ +#define VNMC_SCLE (1 << 26) /* Gen3 specific */ #define VNMC_FOC (1 << 21) #define VNMC_YCAL (1 << 19) #define VNMC_INF_YUV8_BT656(0 << 16) @@ -119,6 +125,13 @@ #define VNDMR2_FTEV(1 << 17) #define VNDMR2_VLV(n) ((n & 0xf) << 12) +/* Video n CSI2 Interface Mode Register (Gen3) */ +#define VNCSI_IFMD_DES2(1 << 27) +#define VNCSI_IFMD_DES1(1 << 26) +#define VNCSI_IFMD_DES0(1 << 25) +#define VNCSI_IFMD_CSI_CHSEL(n) (((n) & 0xf) << 0) +#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf + struct rvin_buffer { struct vb2_v4l2_buffer vb; struct list_head list; @@ -514,28 +527,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs) rvin_write(vin, p_set->coeff_set[23], VNC8C_REG); } -void rvin_crop_scale_comp(struct rvin_dev *vin) +static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin) { u32 xs, ys; - /* Set Start/End Pixel/Line Pre-Clip */ - rvin_write(vin, vin->crop.left, VNSPPRC_REG); - rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG); - switch (vin->format.field) { - case V4L2_FIELD_INTERLACED: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG); - rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1, - VNELPRC_REG); - break; - default: - rvin_write(vin, vin->crop.top, VNSLPRC_REG); - rvin_write(vin, vin->crop.top + vin->crop.height - 1, - VNELPRC_REG); - break; - } - /* Set scaling coefficient */ ys = 0; if (vin->crop
[PATCH v10 10/30] rcar-vin: fix handling of single field frames (top, bottom and alternate fields)
There was never proper support in the VIN driver to deliver ALTERNATING field format to user-space, remove this field option. The problem is that ALTERNATING filed order requires the sequence numbers of buffers returned to userspace to reflect if fields where dropped or not, something which is not possible with the VIN drivers capture logic. The VIN driver can still capture from a video source which delivers frames in ALTERNATING field order, but needs to combine them using the VIN hardware into INTERLACED field order. Before this change if a source was delivering fields using ALTERNATE the driver would default to combining them using this hardware feature. Only if the user explicitly requested ALTERNATE filed order would incorrect frames be delivered. The height should not be cut in half for the format for TOP or BOTTOM fields settings. This was a mistake and it was made visible by the scaling refactoring. Correct behavior is that the user should request a frame size that fits the half height frame reflected in the field setting. If not the VIN will do its best to scale the top or bottom to the requested format and cropping and scaling do not work as expected. Signed-off-by: Niklas Söderlund Reviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 15 +--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 53 + 2 files changed, 24 insertions(+), 44 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index fd14be20a6604d7a..c8831e189d362c8b 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -617,7 +617,6 @@ static int rvin_setup(struct rvin_dev *vin) case V4L2_FIELD_INTERLACED_BT: vnmc = VNMC_IM_FULL | VNMC_FOC; break; - case V4L2_FIELD_ALTERNATE: case V4L2_FIELD_NONE: if (vin->continuous) { vnmc = VNMC_IM_ODD_EVEN; @@ -757,18 +756,6 @@ static int rvin_get_active_slot(struct rvin_dev *vin, u32 vnms) return 0; } -static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) -{ - if (vin->format.field == V4L2_FIELD_ALTERNATE) { - /* If FS is set it's a Even field */ - if (vnms & VNMS_FS) - return V4L2_FIELD_BOTTOM; - return V4L2_FIELD_TOP; - } - - return vin->format.field; -} - static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) { const struct rvin_video_format *fmt; @@ -941,7 +928,7 @@ static irqreturn_t rvin_irq(int irq, void *data) goto done; /* Capture frame */ - vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms); + vin->queue_buf[slot]->field = vin->format.field; vin->queue_buf[slot]->sequence = sequence; vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 4d5be2d0c79c9c9a..9f7902d29c62e205 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -103,6 +103,28 @@ static int rvin_get_source_format(struct rvin_dev *vin, if (ret) return ret; + switch (fmt.format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + break; + case V4L2_FIELD_ALTERNATE: + /* +* Driver do not (yet) support outputting ALTERNATE to a +* userspace. It dose support outputting INTERLACED so use +* the VIN hardware to combine the two fields. +*/ + fmt.format.field = V4L2_FIELD_INTERLACED; + fmt.format.height *= 2; + break; + default: + vin->format.field = V4L2_FIELD_NONE; + break; + } + memcpy(mbus_fmt, &fmt.format, sizeof(*mbus_fmt)); return 0; @@ -139,33 +161,6 @@ static int rvin_reset_format(struct rvin_dev *vin) v4l2_fill_pix_format(&vin->format, &source_fmt); - /* -* If the subdevice uses ALTERNATE field mode and G_STD is -* implemented use the VIN HW to combine the two fields to -* one INTERLACED frame. The ALTERNATE field mode can still -* be requested in S_FMT and be respected, this is just the -* default which is applied at probing or when S_STD is called. -*/ - if (vin->format.field == V4L2_FIELD_ALTERNATE && - v4l2_subdev_has_op(vin_to_source(vin), video, g_std)) - vin->format.field = V4L2_FIELD_INTERLACED; - - switch (vin-
Re: [PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
On Mon, Jan 29, 2018 at 04:46:37PM +0100, Geert Uytterhoeven wrote: > Hi Simon, > > On Mon, Jan 29, 2018 at 4:19 PM, Simon Horman wrote: > > On Mon, Jan 29, 2018 at 04:01:49PM +0100, Geert Uytterhoeven wrote: > >> On Mon, Jan 29, 2018 at 3:24 PM, Simon Horman wrote: > >> > On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote: > >> >> On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman wrote: > >> >> > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote: > >> >> >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman > >> >> >> wrote: > >> >> >> > From: Takeshi Kihara > >> >> >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC. > >> >> >> > > >> >> >> > Signed-off-by: Takeshi Kihara > >> >> >> > Signed-off-by: Simon Horman > >> >> > >> >> >> As the CPG/MSSR driver now has suspend/resume support, do we need > >> >> >> a notifier to restore the Z or Z2 registers? Or is that handled > >> >> >> automatically > >> >> >> by cpufreq during system resume, for both the primary and the > >> >> >> secondary > >> >> >> CPU cores? > >> >> > > >> >> > I am a bit unsure. > >> >> > > >> >> > When using the A57 cores, which is the default case, the Z clk is > >> >> > queried > >> >> > by CPUFreq on resume. It appears that on my system its already set to > >> >> > the > >> >> > correct value but I assume if it was not then it would be reset. > >> >> > However, > >> >> > this does not cover Z2 clk. So perhaps to be safe we need to register > >> >> > notifiers and make sure they they play nicely with CPUFreq? > >> >> > >> >> Of course the CPU is special: unlike many other devices, it must be > >> >> running > >> >> when the kernel is reentered upon system resume. > >> >> It may be running using a different frequency setting, though. > >> >> However, following "opp-suspend", the system will always suspend with > >> >> the > >> >> Z clock running at 1.5GHz, which is the default? > >> >> So Z is probably OK. > >> >> > >> >> It's more interesting to check what happens when the little cores are > >> >> enabled as well (unfortunately that requires different firmware). > >> >> 1. Does cpufreq handle them correctly when they are onlined again during > >> >>system resume? > >> > > >> > I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS > >> > using the instructions at > >> > https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support > >> > >> > # grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary > >> > z2 00 119808 > >> > 0 0 > >> >.pll1 11 319488 > >> > 0 0 > >> >.pll0 00 299520 > >> > 0 0 > >> > z 00 149760 > >> > 0 0 > >> > >> You know it's PLL2, not PLL1, you want to look at? ;-) > > > > Sorry, I will double check but I had looked at PLL2 earlier: > > I just messed things up when preparing things to post in email. > > > >> Thanks for checking, looks all good! > > > > Ok, so do you think we can merge this series with > > the off-by-one problem fixed? > > Yes we can. Thanks! Excellent.
Re: [PATCH v3 11/16] mmc: tmio: deprecate "toshiba,mmc-wrprotect-disable" DT property
On Thu, Jan 18, 2018 at 10:58:36AM +0900, Masahiro Yamada wrote: > 2018-01-18 1:28 GMT+09:00 Masahiro Yamada : > > This property is equivalent to "disable-wp" defined in > > Documentation/devicetree/bindings/mmc/tmio_mmc.txt > > This is mistake. > > "disable-wp" is defined in > > Documentation/devicetree/bindings/mmc/mmc.txt > > > > > > The TMIO MMC core calls mmc_of_parse(), and it sets > > MMC_CAP2_NO_WRITE_PROTECT if "disable-wp" property is present. > > > > We do not need a vendor-specific property to do the same thing. > > > > Let's remove the description from the dt-binding to prevent new boards > > from using it. > > > > I am keeping the driver code for existing DT files, but added > > comments that this is deprecated. > > > > Signed-off-by: Masahiro Yamada > > --- > > > > Changes in v3: > > - newly added > > > > Changes in v2: None > > > > Documentation/devicetree/bindings/mmc/tmio_mmc.txt | 1 - Other than the above, Acked-by: Rob Herring > > drivers/mmc/host/tmio_mmc_core.c | 5 + > > 2 files changed, 5 insertions(+), 1 deletion(-)
[PATCH v5 1/6] clk: renesas: rcar-gen3: Add Z clock divider support
From: Takeshi Kihara This patch adds Z clock divider support for R-Car Gen3 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman --- v4 [Simon Horman] * Rebase * Divide parent clock by 2 to give correct rate (again) * Take care not to overflow multiplication on 32 but platforms v3 [Simon Horman] * Use DIV_ROUND_CLOSEST_ULL instead of open-coding the same behaviour using div_u64() * Do not round rate to 100MHz in cpg_z_clk_recalc_rate * Remove calculation for PLL post-divider, this is bogus. Instead do not round to closest in cpg_z_clk_round_rate() * Drop check for !prate in cpg_z_clk_round_rate v1 [Simon Horman] * Divide parent clock by 2 to give correct rate * Use GENMASK, FIELD_{GET,PREP} * Correct whitespace * Arrange local variables in reverse Christmas tree order v0 [Takeshi Kihara] --- drivers/clk/renesas/rcar-gen3-cpg.c | 133 drivers/clk/renesas/rcar-gen3-cpg.h | 1 + 2 files changed, 134 insertions(+) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 0904886f5501..b85918fa62c6 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -62,6 +63,134 @@ static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, } /* + * Z Clock + * + * Traits of this clock: + * prepare - clk_prepare only ensures that parents are prepared + * enable - clk_enable only ensures that parents are enabled + * rate - rate is adjustable. clk->rate = (parent->rate * mult / 32 ) / 2 + * parent - fixed parent. No clk_set_parent support + */ +#define CPG_FRQCRB 0x0004 +#define CPG_FRQCRB_KICKBIT(31) +#define CPG_FRQCRC 0x00e0 +#define CPG_FRQCRC_ZFC_MASKGENMASK(12, 8) + +struct cpg_z_clk { + struct clk_hw hw; + void __iomem *reg; + void __iomem *kick_reg; +}; + +#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) + +static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + + mult = 32 - FIELD_GET(CPG_FRQCRC_ZFC_MASK, clk_readl(zclk->reg)); + + /* Factor of 2 is for fixed divider */ + return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * 2); +} + +static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, +unsigned long *parent_rate) +{ + /* Factor of 2 is for fixed divider */ + unsigned long prate = *parent_rate / 2; + unsigned int mult; + + mult = div_u64(rate * 32ULL, prate); + mult = clamp(mult, 1U, 32U); + + return (u64)prate * mult / 32; +} + +static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + unsigned int i; + u32 val, kick; + + /* Factor of 2 is for fixed divider */ + mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate); + mult = clamp(mult, 1U, 32U); + + if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) + return -EBUSY; + + val = clk_readl(zclk->reg) & ~CPG_FRQCRC_ZFC_MASK; + val |= FIELD_PREP(CPG_FRQCRC_ZFC_MASK, 32 - mult); + clk_writel(val, zclk->reg); + + /* +* Set KICK bit in FRQCRB to update hardware setting and wait for +* clock change completion. +*/ + kick = clk_readl(zclk->kick_reg); + kick |= CPG_FRQCRB_KICK; + clk_writel(kick, zclk->kick_reg); + + /* +* Note: There is no HW information about the worst case latency. +* +* Using experimental measurements, it seems that no more than +* ~10 iterations are needed, independently of the CPU rate. +* Since this value might be dependent of external xtal rate, pll1 +* rate or even the other emulation clocks rate, use 1000 as a +* "super" safe value. +*/ + for (i = 1000; i; i--) { + if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) + return 0; + + cpu_relax(); + } + + return -ETIMEDOUT; +} + +static const struct clk_ops cpg_z_clk_ops = { + .recalc_rate = cpg_z_clk_recalc_rate, + .round_rate = cpg_z_clk_round_rate, + .set_rate = cpg_z_clk_set_rate, +}; + +static struct clk * __init cpg_z_clk_register(const char *name, + const char *parent_name, + void __iomem *reg) +{ + struct clk_init_data init; + struct cpg_z_clk *zclk; + struct clk *clk; + + zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); + if (!zclk) + return
[PATCH v5 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
From: Takeshi Kihara This patch adds Z2 clock divider support for R-Car Gen3 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman --- v5 [Simon Horman] * Correct off-by-one error in use of __ffs() v4 [Simon Horman] * Rebase * Use __ffs as FIELD_{GET,PREP} don't not work with non-constant masks * Use correct mask in cpg_z_clk_recalc_rate() v3 [Simon Horman] * Consolidate Z and Z2 clock ops * Allow setting of Z2 clock v1 [Simon Horman] * Provide __cpg_z_clk_recalc_rate() helper * Use GENMASK v0 [Takeshi Kihara] --- drivers/clk/renesas/rcar-gen3-cpg.c | 22 -- drivers/clk/renesas/rcar-gen3-cpg.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index b85918fa62c6..0c8fe10d57fe 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -63,7 +63,7 @@ static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, } /* - * Z Clock + * Z Clock & Z2 Clock * * Traits of this clock: * prepare - clk_prepare only ensures that parents are prepared @@ -75,11 +75,13 @@ static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, #define CPG_FRQCRB_KICKBIT(31) #define CPG_FRQCRC 0x00e0 #define CPG_FRQCRC_ZFC_MASKGENMASK(12, 8) +#define CPG_FRQCRC_Z2FC_MASK GENMASK(4, 0) struct cpg_z_clk { struct clk_hw hw; void __iomem *reg; void __iomem *kick_reg; + unsigned long mask; }; #define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) @@ -89,8 +91,10 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, { struct cpg_z_clk *zclk = to_z_clk(hw); unsigned int mult; + u32 val; - mult = 32 - FIELD_GET(CPG_FRQCRC_ZFC_MASK, clk_readl(zclk->reg)); + val = clk_readl(zclk->reg) & zclk->mask; + mult = 32 - (val >> __ffs(zclk->mask)); /* Factor of 2 is for fixed divider */ return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * 2); @@ -124,8 +128,8 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) return -EBUSY; - val = clk_readl(zclk->reg) & ~CPG_FRQCRC_ZFC_MASK; - val |= FIELD_PREP(CPG_FRQCRC_ZFC_MASK, 32 - mult); + val = clk_readl(zclk->reg) & ~zclk->mask; + val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask; clk_writel(val, zclk->reg); /* @@ -163,7 +167,8 @@ static const struct clk_ops cpg_z_clk_ops = { static struct clk * __init cpg_z_clk_register(const char *name, const char *parent_name, - void __iomem *reg) + void __iomem *reg, + unsigned long mask) { struct clk_init_data init; struct cpg_z_clk *zclk; @@ -182,6 +187,7 @@ static struct clk * __init cpg_z_clk_register(const char *name, zclk->reg = reg + CPG_FRQCRC; zclk->kick_reg = reg + CPG_FRQCRB; zclk->hw.init = &init; + zclk->mask = mask; clk = clk_register(NULL, &zclk->hw); if (IS_ERR(clk)) @@ -551,7 +557,11 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN3_Z: return cpg_z_clk_register(core->name, __clk_get_name(parent), - base); + base, CPG_FRQCRC_ZFC_MASK); + + case CLK_TYPE_GEN3_Z2: + return cpg_z_clk_register(core->name, __clk_get_name(parent), + base, CPG_FRQCRC_Z2FC_MASK); default: return ERR_PTR(-EINVAL); diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index c73d4d6fdc85..ea4f8fc3c4c9 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -22,6 +22,7 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_R, CLK_TYPE_GEN3_PE, CLK_TYPE_GEN3_Z, + CLK_TYPE_GEN3_Z2, }; #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ -- 2.11.0
[PATCH v5 0/6] clk: renesas: r8a779[56]: Add Z and Z2 clock support
Hi, this patch-set adds Z and Z2 clock support. These are dependencies for supporting CPUFreq. The remainder of that work is being posted separately and can be found at: https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git topic/rcar-gen3-cpufreq-v5 Based on v4.15-rc1 Changes since v4: * Correct off-by one error in usage of __ffs Changes since v3: * Rebase * Divide parent clock by 2 to give correct rate (again) * Take care not to overflow multiplication on 32 but platforms * Use __ffs as FIELD_{GET,PREP} don't not work with non-constant masks * Use correct mask in cpg_z_clk_recalc_rate() Changes since v2: * Rebase * Address review of v2 as noted in patch changelogs Takeshi Kihara (6): clk: renesas: rcar-gen3: Add Z clock divider support clk: renesas: rcar-gen3: Add Z2 clock divider support clk: renesas: r8a7795: Add Z clock clk: renesas: r8a7795: Add Z2 clock clk: renesas: r8a7796: Add Z clock clk: renesas: r8a7796: Add Z2 clock drivers/clk/renesas/r8a7795-cpg-mssr.c | 2 + drivers/clk/renesas/r8a7796-cpg-mssr.c | 2 + drivers/clk/renesas/rcar-gen3-cpg.c| 143 + drivers/clk/renesas/rcar-gen3-cpg.h| 2 + 4 files changed, 149 insertions(+) Results of testing this on an H3 ES2.0 / Salvator-XS are as below. Testing has shown equivalent results on an M3W ES1.0 / Salvator-X. Testing has also shown equivalent results on an H3 ES1.0 / Salvator-X with the following restrictions due to lack of physical access: 1. No little CPUs are brought up and thus scaling the frequency of those CPUs was not tested 2. No Suspend-to-RAM The results for H3 ES2.0 / Salvator-XS: On Boot --- Z clock is half of pll0 and corresponds to CPU frequency. Z2 clock is half pll2. This is as expected. # cd /sys/devices/system/cpu/ # grep -E -w "pll[02]|z|z2" /sys/kernel/debug/clk/clk_summary .pll2 00 239616 0 0 z2 00 119808 0 0 .pll0 00 299520 0 0 z 00 149760 0 0 # grep . cpu*/cpufreq/*cur* cpu0/cpufreq/cpuinfo_cur_freq:1497600 cpu0/cpufreq/scaling_cur_freq:1497600 cpu1/cpufreq/cpuinfo_cur_freq:1497600 cpu1/cpufreq/scaling_cur_freq:1497600 cpu2/cpufreq/cpuinfo_cur_freq:1497600 cpu2/cpufreq/scaling_cur_freq:1497600 cpu3/cpufreq/cpuinfo_cur_freq:1497600 cpu3/cpufreq/scaling_cur_freq:1497600 cpu4/cpufreq/cpuinfo_cur_freq:1198080 cpu4/cpufreq/scaling_cur_freq:1198080 cpu5/cpufreq/cpuinfo_cur_freq:1198080 cpu5/cpufreq/scaling_cur_freq:1198080 cpu6/cpufreq/cpuinfo_cur_freq:1198080 cpu6/cpufreq/scaling_cur_freq:1198080 cpu7/cpufreq/cpuinfo_cur_freq:1198080 cpu7/cpufreq/scaling_cur_freq:1198080 BIG CPU Freq scaled to 50 and little CPU Freq scaled to 80 -- Z and Z2 clocks corresponds to new CPU frequencies. PLL0 and PLL2 are unchanged. This is the expected result. # echo 50 > cpu0/cpufreq/scaling_max_freq # echo 80 > cpu4/cpufreq/scaling_max_freq # grep -E -w "pll[02]|z|z2" /sys/kernel/debug/clk/clk_summary .pll2 00 239616 0 0 z2 00 78624 0 0 .pll0 00 299520 0 0 z 00 46800 0 0 # grep . cpu*/cpufreq/*cur* cpu0/cpufreq/cpuinfo_cur_freq:468000 cpu0/cpufreq/scaling_cur_freq:468000 cpu1/cpufreq/cpuinfo_cur_freq:468000 cpu1/cpufreq/scaling_cur_freq:468000 cpu2/cpufreq/cpuinfo_cur_freq:468000 cpu2/cpufreq/scaling_cur_freq:468000 cpu3/cpufreq/cpuinfo_cur_freq:468000 cpu3/cpufreq/scaling_cur_freq:468000 cpu4/cpufreq/cpuinfo_cur_freq:786240 cpu4/cpufreq/scaling_cur_freq:786240 cpu5/cpufreq/cpuinfo_cur_freq:786240 cpu5/cpufreq/scaling_cur_freq:786240 cpu6/cpufreq/cpuinfo_cur_freq:786240 cpu6/cpufreq/scaling_cur_freq:786240 cpu7/cpufreq/cpuinfo_cur_freq:786240 cpu7/cpufreq/scaling_cur_freq:786240 After Resume from Suspend-to-RAM Clocks and CPU freqiencies are restored to their values before suspend. This is the expected result. # grep -E -w "pll[02]|z|z2" /sys/kernel/debug/clk/clk_summary .pll2 00 239616 0 0 z2 00 78624 0 0 .pll0 00 299520 0 0 z 00 46800 0 0 # grep . cpu*/cpufreq/*cur* cpu0/cpufreq/cpuinfo_cur_freq:468000 cpu0/cpufreq/scaling_cur_freq:50 cpu1/cpufreq/cpuinfo_cur_freq:468000 cpu1/cpufreq/scaling_cur_freq:50 cpu2/cpufr
[PATCH v5 3/6] clk: renesas: r8a7795: Add Z clock
From: Takeshi Kihara This patch adds Z clock for R8A7795 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index b1d9f48eae9e..995a4c4fb01e 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -74,6 +74,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), /* Core Clock Outputs */ + DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), DEF_FIXED("ztr",R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7795_CLK_ZT,CLK_PLL1_DIV2, 4, 1), -- 2.11.0
[PATCH v5 6/6] clk: renesas: r8a7796: Add Z2 clock
From: Takeshi Kihara This patch adds Z2 clock for R8A7796 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 82b444ac66c6..83a68e51e4ec 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -75,6 +75,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { /* Core Clock Outputs */ DEF_BASE("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_BASE("z2", R8A7796_CLK_Z2,CLK_TYPE_GEN3_Z2, CLK_PLL2), DEF_FIXED("ztr",R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7796_CLK_ZT,CLK_PLL1_DIV2, 4, 1), -- 2.11.0
[PATCH v5 4/6] clk: renesas: r8a7795: Add Z2 clock
From: Takeshi Kihara This patch adds Z2 clock for r8a7795 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index 995a4c4fb01e..775b0ceaa337 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -75,6 +75,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { /* Core Clock Outputs */ DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_BASE("z2", R8A7795_CLK_Z2,CLK_TYPE_GEN3_Z2, CLK_PLL2), DEF_FIXED("ztr",R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7795_CLK_ZT,CLK_PLL1_DIV2, 4, 1), -- 2.11.0
[PATCH v5 5/6] clk: renesas: r8a7796: Add Z clock
From: Takeshi Kihara This patch adds Z clock for R8A7796 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman Reviewed-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index b3767472088a..82b444ac66c6 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -74,6 +74,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), /* Core Clock Outputs */ + DEF_BASE("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), DEF_FIXED("ztr",R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("zt", R8A7796_CLK_ZT,CLK_PLL1_DIV2, 4, 1), -- 2.11.0
[PATCH 0/2] arm64: dts: renesas: Update OPPs to support CA53 dfs
Describe frequencies, other than the default for CA53 cores. This is a pre-requisite for using providing alternative frequencies for use with CPUFreq with these cores. CPUFreq requires Z and Z2 clock support to function. That this patchset and that dependency can be found at: https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git topic/rcar-gen3-cpufreq-v5 Dien Pham (2): arm64: dts: r8a7796: Update OPPs to support CA53 dfs arm64: dts: r8a7795: Update OPPs to support CA53 dfs arch/arm64/boot/dts/renesas/r8a7795.dtsi | 10 ++ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 16 2 files changed, 26 insertions(+) -- 2.11.0
[PATCH 2/2] arm64: dts: r8a7795: Update OPPs to support CA53 dfs
From: Dien Pham Describe frequencies, other than the default for CA53 cores. This is a pre-requisite for using providing alternative frequencies for use with CPUFreq with these cores. Signed-off-by: Dien Pham Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index ce85704976f0..086057cffe7f 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -223,6 +223,16 @@ compatible = "operating-points-v2"; opp-shared; + opp-8 { + opp-hz = /bits/ 64 <8>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; + opp-10 { + opp-hz = /bits/ 64 <10>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; opp-12 { opp-hz = /bits/ 64 <12>; opp-microvolt = <82>; -- 2.11.0
[PATCH 1/2] arm64: dts: r8a7796: Update OPPs to support CA53 dfs
From: Dien Pham Describe frequencies, other than the default for CA53 cores. This is a pre-requisite for using providing alternative frequencies for use with CPUFreq with these cores. Signed-off-by: Dien Pham Signed-off-by: Takeshi Kihara Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7796.dtsi | 16 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index f8e9313f9405..0c7ad930aebf 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -204,11 +204,27 @@ compatible = "operating-points-v2"; opp-shared; + opp-8 { + opp-hz = /bits/ 64 <8>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; + opp-10 { + opp-hz = /bits/ 64 <10>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + }; opp-12 { opp-hz = /bits/ 64 <12>; opp-microvolt = <82>; clock-latency-ns = <30>; }; + opp-13 { + opp-hz = /bits/ 64 <13>; + opp-microvolt = <82>; + clock-latency-ns = <30>; + turbo-mode; + }; }; /* External PCIe clock - can be overridden by the board */ -- 2.11.0
Re: [PATCH v2 1/2] DT: display: renesas,du: document R8A77970 bindings
On Fri, Jan 19, 2018 at 12:05:58AM +0300, Sergei Shtylyov wrote: > Document the R-Car V3M (R8A77970) SoC in the R-Car DU bindings. > > Signed-off-by: Sergei Shtylyov > > --- > Changes in version 2: > - documented R8A77970 DU ports; > - patch split from the main R8A77970 DU support patch. > > Documentation/devicetree/bindings/display/renesas,du.txt |2 ++ > 1 file changed, 2 insertions(+) Acked-by: Rob Herring The preferred subject prefix is "dt-bindings: display: ..."
Re: [PATCH v2 1/2] DT: display: renesas,du: document R8A77970 bindings
On 01/29/2018 10:02 PM, Rob Herring wrote: >> Document the R-Car V3M (R8A77970) SoC in the R-Car DU bindings. >> >> Signed-off-by: Sergei Shtylyov >> >> --- >> Changes in version 2: >> - documented R8A77970 DU ports; >> - patch split from the main R8A77970 DU support patch. >> >> Documentation/devicetree/bindings/display/renesas,du.txt |2 ++ >> 1 file changed, 2 insertions(+) > > Acked-by: Rob Herring Thank you! > The preferred subject prefix is "dt-bindings: display: ..." I use it for the stuff in include/dt-bindings/. :-) MBR, Sergei
Re: [PATCH 2/3] DT: display: renesas,lvds: document R8A77970 bindings
On Fri, Jan 19, 2018 at 09:29:20PM +0300, Sergei Shtylyov wrote: > Document the R-Car V3M (R8A77970) SoC in the R-Car LVDS bindings. > > Signed-off-by: Sergei Shtylyov > > --- > Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt |1 + > 1 file changed, 1 insertion(+) Reviewed-by: Rob Herring
Re: [PATCH 2/2] drm: adv7511: Add support for i2c_new_secondary_device
On Mon, Jan 29, 2018 at 12:26:00PM +0200, Laurent Pinchart wrote: > Hi Kieran, > > Thank you for the patch. > > On Monday, 22 January 2018 14:50:00 EET Kieran Bingham wrote: > > The ADV7511 has four 256-byte maps that can be accessed via the main I²C > > ports. Each map has it own I²C address and acts as a standard slave > > device on the I²C bus. > > > > Allow a device tree node to override the default addresses so that > > address conflicts with other devices on the same bus may be resolved at > > the board description level. > > > > Signed-off-by: Kieran Bingham > > --- > > .../bindings/display/bridge/adi,adv7511.txt| 10 +- > > I don't mind personally, but device tree maintainers usually ask for DT > bindings changes to be split to a separate patch. Or perfect bindings, then I won't ask to split it just for that (usually). > > drivers/gpu/drm/bridge/adv7511/adv7511.h | 4 +++ > > drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 36 --- > > 3 files changed, 37 insertions(+), 13 deletions(-)
Re: [PATCH 2/2] drm: adv7511: Add support for i2c_new_secondary_device
On Mon, Jan 22, 2018 at 12:50:01PM +, Kieran Bingham wrote: > The ADV7511 has four 256-byte maps that can be accessed via the main I²C > ports. Each map has it own I²C address and acts as a standard slave > device on the I²C bus. > > Allow a device tree node to override the default addresses so that > address conflicts with other devices on the same bus may be resolved at > the board description level. > > Signed-off-by: Kieran Bingham > --- > .../bindings/display/bridge/adi,adv7511.txt| 10 +- Reviewed-by: Rob Herring > drivers/gpu/drm/bridge/adv7511/adv7511.h | 4 +++ > drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 36 > ++ > 3 files changed, 37 insertions(+), 13 deletions(-)
Re: [PATCH 1/2] media: adv7604: Add support for i2c_new_secondary_device
On Mon, Jan 22, 2018 at 12:49:56PM +, Kieran Bingham wrote: > From: Jean-Michel Hautbois > > The ADV7604 has thirteen 256-byte maps that can be accessed via the main > I²C ports. Each map has it own I²C address and acts as a standard slave > device on the I²C bus. > > Allow a device tree node to override the default addresses so that > address conflicts with other devices on the same bus may be resolved at > the board description level. > > Signed-off-by: Jean-Michel Hautbois > [Kieran: Re-adapted for mainline] > Signed-off-by: Kieran Bingham > --- > Based upon the original posting : > https://lkml.org/lkml/2014/10/22/469 > --- > .../devicetree/bindings/media/i2c/adv7604.txt | 18 ++- Reviewed-by: Rob Herring In the future, please split bindings to separate patch. > drivers/media/i2c/adv7604.c| 60 > ++ > 2 files changed, 55 insertions(+), 23 deletions(-)