Re: [PATCH v1 05/24] clk: wrap I/O access for improved portability
On Mon, Jul 15, 2013 at 21:38 +0200, Sascha Hauer wrote: > > On Mon, Jul 15, 2013 at 08:47:34PM +0200, Gerhard Sittig wrote: > > diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c > > index 6d55eb2..2c07061 100644 > > --- a/drivers/clk/clk-divider.c > > +++ b/drivers/clk/clk-divider.c > > @@ -104,7 +104,7 @@ static unsigned long clk_divider_recalc_rate(struct > > clk_hw *hw, > > struct clk_divider *divider = to_clk_divider(hw); > > unsigned int div, val; > > > > - val = readl(divider->reg) >> divider->shift; > > + val = clk_readl(divider->reg) >> divider->shift; > > val &= div_mask(divider); > > Would it be an option to use regmap for the generic dividers/muxes > instead? This should be suitable for ppc and also for people who want to > use the generic clocks on i2c devices. Some other thought crossed my mind regarding access to clock control registers that reside behind some communication channel like I2C: The common clock API assumes (it's part of the contract) that there are potentially expensive operations like get, put, prepare and unprepare, as well as swift and non-blocking operations like enable and disable. Would the regmap abstraction hide the potentially blocking nature of a register access (I understand that you can implement "local" as well as "remote" register sets by this mechanism)? Or could you still meet the assumptions or requirements of the common clock API? It might as well be the responsibility of the clock driver's implementor to arrange for the availability of non-blocking enable/disable operations, just as it is today. Such that expensive register access need not be forbidden in general. virtually yours Gerhard Sittig -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: off...@denx.de ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v1 05/24] clk: wrap I/O access for improved portability
On Thu, Jul 18, 2013 at 09:04:02AM +0200, Gerhard Sittig wrote: > On Mon, Jul 15, 2013 at 21:38 +0200, Sascha Hauer wrote: > > > > On Mon, Jul 15, 2013 at 08:47:34PM +0200, Gerhard Sittig wrote: > > > diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c > > > index 6d55eb2..2c07061 100644 > > > --- a/drivers/clk/clk-divider.c > > > +++ b/drivers/clk/clk-divider.c > > > @@ -104,7 +104,7 @@ static unsigned long clk_divider_recalc_rate(struct > > > clk_hw *hw, > > > struct clk_divider *divider = to_clk_divider(hw); > > > unsigned int div, val; > > > > > > - val = readl(divider->reg) >> divider->shift; > > > + val = clk_readl(divider->reg) >> divider->shift; > > > val &= div_mask(divider); > > > > Would it be an option to use regmap for the generic dividers/muxes > > instead? This should be suitable for ppc and also for people who want to > > use the generic clocks on i2c devices. > > Some other thought crossed my mind regarding access to clock > control registers that reside behind some communication channel > like I2C: > > The common clock API assumes (it's part of the contract) that > there are potentially expensive operations like get, put, prepare > and unprepare, as well as swift and non-blocking operations like > enable and disable. > > Would the regmap abstraction hide the potentially blocking nature > of a register access (I understand that you can implement "local" > as well as "remote" register sets by this mechanism)? Or could > you still meet the assumptions or requirements of the common > clock API? > > It might as well be the responsibility of the clock driver's > implementor to arrange for the availability of non-blocking > enable/disable operations, just as it is today. Such that > expensive register access need not be forbidden in general. regmap for mmio uses a spinlock for read/modify/write operations, just like you have to use a spinlock in the common clk dividers/gates. This part wouldn't change with regmap. For i2c connected clocks where a spinlock doesn't work due to the nonatomic nature of i2c devices we would have to move the enable/disble stuff to prepare/unprepare in the common gate code. This can be left for someone who works on i2c clocks though. I think regmap has the potential to solve a number of issues like the hardcoded readl/writel in the common clock blocks, issues with i2c clocks and your endianess issue. The biggest question probably is how to get there without putting too much of a burden on you. It's probably not an option to convert all users to regmap, so it seems additional functions like clk_register_gate_regmap are better to handle. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v1 05/24] clk: wrap I/O access for improved portability
On Thu, Jul 18, 2013 at 09:04:02AM +0200, Gerhard Sittig wrote: > The common clock API assumes (it's part of the contract) that > there are potentially expensive operations like get, put, prepare > and unprepare, as well as swift and non-blocking operations like > enable and disable. Let's get something straight here, because what you've said above is wrong. 1. clk_get() and clk_put() are NOT part of the common clock API. They're separate - they're part of the clk API, and the infrastructure behind that is clkdev, which is a separately owned thing (by me.) 2. The "contract" of the clk API is defined by the clk API, not by some random implementation like the common clock API. The clk API is maintained by myself, and is described in include/linux/clk.h 3. clk_prepare() and clk_unprepare() are functions MUST only be called from contexts where sleeping is permitted. These functions MAY sleep for whatever reason they require to, and as long as they require to. (This is the whole reason these two functions were created in the first place.) 4. clk_enable() and clk_disable() MAY be called from any context, but MUST never sleep. If you need to talk over a non-atomic bus for these, then these functions should be no-ops, and the code which does that must be executed from the clk_prepare()/clk_unprepare() operations. That is the "clk API" contract. The CCF has no bearing on this; if it disagrees, then the CCF is buggy and is non-conformant. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v1 05/24] clk: wrap I/O access for improved portability
On Thu, Jul 18, 2013 at 10:06:57AM +0200, Sascha Hauer wrote: > I think regmap has the potential to solve a number of issues like the > hardcoded readl/writel in the common clock blocks, issues with i2c > clocks and your endianess issue. The biggest question probably is how > to get there without putting too much of a burden on you. It's probably > not an option to convert all users to regmap, so it seems additional > functions like clk_register_gate_regmap are better to handle. That's basically what regulator does. There's versions of the ops that all the drivers can use. signature.asc Description: Digital signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 3/4 V2] mmc: esdhc: Correct host version of T4240-R1.0
On 07/17/2013 09:30:45 PM, Zang Roy-R61911 wrote: > -Original Message- > From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc- > ow...@vger.kernel.org] On Behalf Of Scott Wood > > On 07/17/2013 05:11:30 AM, Haijun Zhang wrote: > > Vender version and sdhc spec version of T4240-R1.0 is incorrect. > > The right value should be VVN=0x13, SVN = 0x1. The wrong version > > number will break down the ADMA data transfer. > > This defect only exist in T4240-R1.0. Will be fixed in T4240-R2.0. > > Also share vvn and svr for public use. > > > > Signed-off-by: Haijun Zhang > > We're not supporting T4240 rev 1.0 in upstream Linux, as it's not > production silicon. As discussed, production silicon Rev 2.0 will also suffer this issue. So need to address it beyond T4240-R2.0. OK -- please update the commit message. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 00/24] add COMMON_CLK support for PowerPC MPC512x
this series introduces support for the common clock framework (CCF, COMMON_CLK Kconfig option) in the PowerPC based MPC512x platform although the series does touch several subsystems -- serial, spi, net (can, fs_enet), mtd (nfc), usb, i2c, media (viu), and dts -- all of the patches are strictly clock related it appears most appropriate to take this series through either the clk or the powerpc trees after it has passed review and other subsystem maintainers ACKed the clock setup related driver modifications the series passes 'checkpatch.pl --strict' except for one warning which cannot get resolved, since that either breaks compilation (the data type is preset by the clk-provider.h API) or requires a cast which shadows real mismatches: WARNING: static const char * array should probably be static const char * const #413: FILE: arch/powerpc/platforms/512x/clock-commonclk.c:335: +static const char *parent_names_mux0[] = { total: 0 errors, 1 warnings, 0 checks, 836 lines checked each step in the series was build and run tested (with a display that is attached to the DIU as well as SPI, with an SPI attached NOR flash, with multiple UART ports such that one is not the boot console, with EEPROMs attached to I2C, with an SD card, booting from network) changes in v2: - cleanup of the UART and SPI clock handling before the introduction of common clock support for the platform, as incomplete clock handling becomes fatal or more dangerous later (which in turn changes the context of the "device tree lookup only" followup patch later) - reordered the sequence of patches to keep the serial communication related parts together (UART, SPI, and PSC FIFO changes after common clock support was introduced) - updated commit messages for the clock API use cleanup in the serial communication drivers, updated comments and reworded commit messages in the core clock driver to expand on the pre-enable workaround and clkdev registration - keep a reference to the PSC FIFO clock during use instead of looking up the clock again in the uninit() routine - remove the clkdev.h header file inclusion directive with the removal of the clkdev registration call Gerhard Sittig (24): spi: mpc512x: cleanup clock API use serial: mpc512x: cleanup clock API use mtd: mpc5121_nfc: prepare clocks before enabling them powerpc: mpc512x: array decl for MCLK registers in CCM clk: wrap I/O access for improved portability dts: mpc512x: prepare for preprocessor support dts: mpc512x: introduce dt-bindings/clock/ header dts: mpc512x: add clock related device tree specs clk: mpc512x: introduce COMMON_CLK for MPC512x dts: mpc512x: add clock specs for client lookups spi: mpc512x: remove now obsolete clock lookup name serial: mpc512x: remove now obsolete clock lookup name clk: mpc512x: remove now obsolete clkdev registration serial: mpc512x: setup the PSC FIFO clock as well net: can: mscan: add a comment on reg to idx mapping net: can: mscan: make mpc512x code use common clock powerpc/mpc512x: improve DIU related clock setup i2c: mpc: OF clock lookup for MPC512x USB: fsl-mph-dr-of: OF clock lookup, prepare and enable fs_enet: OF clock lookup (non-fatal), prepare and enable [media] fsl-viu: OF clock lookup, prepare before enable powerpc/fsl-pci: OF clock lookup, prepare before enable clk: mpc512x: switch to COMMON_CLK, remove PPC_CLOCK net: can: mscan: remove MPC512x non-COMMON_CLK code path arch/powerpc/boot/dts/ac14xx.dts |9 +- arch/powerpc/boot/dts/include/dt-bindings |1 + arch/powerpc/boot/dts/mpc5121.dtsi | 94 ++- arch/powerpc/boot/dts/mpc5121ads.dts |2 +- arch/powerpc/boot/dts/pdm360ng.dts |2 +- arch/powerpc/include/asm/mpc5121.h | 18 +- arch/powerpc/platforms/512x/Kconfig|2 +- arch/powerpc/platforms/512x/Makefile |3 +- arch/powerpc/platforms/512x/clock-commonclk.c | 761 arch/powerpc/platforms/512x/clock.c| 753 --- arch/powerpc/platforms/512x/mpc512x_shared.c | 165 +++-- arch/powerpc/sysdev/fsl_pci.c | 15 + drivers/clk/clk-divider.c |6 +- drivers/clk/clk-gate.c |6 +- drivers/clk/clk-mux.c |6 +- drivers/i2c/busses/i2c-mpc.c |9 + drivers/media/platform/fsl-viu.c | 12 +- drivers/mtd/nand/mpc5121_nfc.c |4 +- drivers/net/can/mscan/mpc5xxx_can.c| 234 +++--- .../net/ethernet/freescale/fs_enet/fs_enet-main.c | 27 +- drivers/spi/spi-mpc512x-psc.c | 45 +- drivers/tty/serial/mpc52xx_uart.c | 137 +++- drivers/usb/host/fsl-mph-dr-of.c | 24 +- include/dt-bindings/clock/mpc512x-clock.h |
[PATCH v2 01/24] spi: mpc512x: cleanup clock API use
cleanup the MPC512x SoC's SPI master's use of the clock API - get, prepare, and enable the MCLK during probe; disable, unprepare and put the MCLK upon remove; hold a reference to the clock over the period of use - fetch MCLK rate (reference) once during probe and slightly reword BCLK (bitrate) determination to reduce redundancy as well as to not exceed the maximum text line length - stick with the PPC_CLOCK 'psc%d_mclk' name for clock lookup, only switch to a fixed string later after device tree based clock lookup will have become available the omission in the clock handling previously went unnoticed, but will become fatal in the common clock scenario Signed-off-by: Gerhard Sittig --- drivers/spi/spi-mpc512x-psc.c | 49 ++--- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 29fce6a..7a32373 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -38,7 +38,8 @@ struct mpc512x_psc_spi { struct mpc512x_psc_fifo __iomem *fifo; unsigned int irq; u8 bits_per_word; - u32 mclk; + struct clk *clk_mclk; + u32 mclk_rate; struct completion txisrdone; }; @@ -72,6 +73,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) struct mpc52xx_psc __iomem *psc = mps->psc; u32 sicr; u32 ccr; + int speed; u16 bclkdiv; sicr = in_be32(&psc->sicr); @@ -95,10 +97,10 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) ccr = in_be32(&psc->ccr); ccr &= 0xFF00; - if (cs->speed_hz) - bclkdiv = (mps->mclk / cs->speed_hz) - 1; - else - bclkdiv = (mps->mclk / 100) - 1;/* default 1MHz */ + speed = cs->speed_hz; + if (!speed) + speed = 100;/* default 1MHz */ + bclkdiv = (mps->mclk_rate / speed) - 1; ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); out_be32(&psc->ccr, ccr); @@ -386,19 +388,11 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, { struct mpc52xx_psc __iomem *psc = mps->psc; struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; - struct clk *spiclk; - int ret = 0; - char name[32]; u32 sicr; u32 ccr; + int speed; u16 bclkdiv; - sprintf(name, "psc%d_mclk", master->bus_num); - spiclk = clk_get(&master->dev, name); - clk_enable(spiclk); - mps->mclk = clk_get_rate(spiclk); - clk_put(spiclk); - /* Reset the PSC into a known state */ out_8(&psc->command, MPC52xx_PSC_RST_RX); out_8(&psc->command, MPC52xx_PSC_RST_TX); @@ -425,7 +419,8 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, ccr = in_be32(&psc->ccr); ccr &= 0xFF00; - bclkdiv = (mps->mclk / 100) - 1;/* default 1MHz */ + speed = 100;/* default 1MHz */ + bclkdiv = (mps->mclk_rate / speed) - 1; ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); out_be32(&psc->ccr, ccr); @@ -445,7 +440,7 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, mps->bits_per_word = 8; - return ret; + return 0; } static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) @@ -479,6 +474,8 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, struct spi_master *master; int ret; void *tempp; + int psc_num; + char clk_name[16]; master = spi_alloc_master(dev, sizeof *mps); if (master == NULL) @@ -521,16 +518,30 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, goto free_master; init_completion(&mps->txisrdone); + psc_num = master->bus_num; + snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); + mps->clk_mclk = clk_get(dev, clk_name); + if (IS_ERR(mps->clk_mclk)) + goto free_irq; + ret = clk_prepare_enable(mps->clk_mclk); + if (ret) + goto free_putclk; + mps->mclk_rate = clk_get_rate(mps->clk_mclk); + ret = mpc512x_psc_spi_port_config(master, mps); if (ret < 0) - goto free_irq; + goto free_disclk; ret = spi_register_master(master); if (ret < 0) - goto free_irq; + goto free_disclk; return ret; +free_disclk: + clk_disable_unprepare(mps->clk_mclk); +free_putclk: + clk_put(mps->clk_mclk); free_irq: free_irq(mps->irq, mps); free_master: @@ -547,6 +558,8 @@ static int mpc512x_psc_spi_do_remove(struct device *dev) struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); spi_unregister_master(master); + clk_disable_unprepare(mps->clk_mclk); +
[PATCH v2 03/24] mtd: mpc5121_nfc: prepare clocks before enabling them
must prepare clocks before enabling them, unprepare after disable Signed-off-by: Gerhard Sittig --- drivers/mtd/nand/mpc5121_nfc.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 3c9cdcb..eb7771d 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -618,7 +618,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) struct mpc5121_nfc_prv *prv = chip->priv; if (prv->clk) { - clk_disable(prv->clk); + clk_disable_unprepare(prv->clk); clk_put(prv->clk); } @@ -737,7 +737,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) goto error; } - clk_enable(prv->clk); + clk_prepare_enable(prv->clk); /* Reset NAND Flash controller */ nfc_set(mtd, NFC_CONFIG1, NFC_RESET); -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 04/24] powerpc: mpc512x: array decl for MCLK registers in CCM
reword the clock control module's registers declaration such that the MCLK related registers form an array and get indexed by PSC number this change is in preparation to COMMON_CLK support for the MPC512x platform, the changed declaration remains neutral to existing code since the PSC and MSCAN CCR fields declared here aren't referenced anywhere Signed-off-by: Gerhard Sittig --- arch/powerpc/include/asm/mpc5121.h | 18 ++ 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/mpc5121.h b/arch/powerpc/include/asm/mpc5121.h index 8ae133e..887d3d6 100644 --- a/arch/powerpc/include/asm/mpc5121.h +++ b/arch/powerpc/include/asm/mpc5121.h @@ -32,25 +32,11 @@ struct mpc512x_ccm { u32 scfr2; /* System Clock Frequency Register 2 */ u32 scfr2s; /* System Clock Frequency Shadow Register 2 */ u32 bcr;/* Bread Crumb Register */ - u32 p0ccr; /* PSC0 Clock Control Register */ - u32 p1ccr; /* PSC1 CCR */ - u32 p2ccr; /* PSC2 CCR */ - u32 p3ccr; /* PSC3 CCR */ - u32 p4ccr; /* PSC4 CCR */ - u32 p5ccr; /* PSC5 CCR */ - u32 p6ccr; /* PSC6 CCR */ - u32 p7ccr; /* PSC7 CCR */ - u32 p8ccr; /* PSC8 CCR */ - u32 p9ccr; /* PSC9 CCR */ - u32 p10ccr; /* PSC10 CCR */ - u32 p11ccr; /* PSC11 CCR */ + u32 psc_ccr[12];/* PSC Clock Control Registers */ u32 spccr; /* SPDIF Clock Control Register */ u32 cccr; /* CFM Clock Control Register */ u32 dccr; /* DIU Clock Control Register */ - u32 m1ccr; /* MSCAN1 CCR */ - u32 m2ccr; /* MSCAN2 CCR */ - u32 m3ccr; /* MSCAN3 CCR */ - u32 m4ccr; /* MSCAN4 CCR */ + u32 mscan_ccr[4]; /* MSCAN Clock Control Registers */ u8 res[0x98]; /* Reserved */ }; -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 05/24] clk: wrap I/O access for improved portability
the common clock drivers were motivated/initiated by ARM development and apparently assume little endian peripherals wrap register/peripherals access in the common code (div, gate, mux) in preparation of adding COMMON_CLK support for other platforms Signed-off-by: Gerhard Sittig --- drivers/clk/clk-divider.c|6 +++--- drivers/clk/clk-gate.c |6 +++--- drivers/clk/clk-mux.c|6 +++--- include/linux/clk-provider.h | 17 + 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 6d55eb2..2c07061 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -104,7 +104,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, struct clk_divider *divider = to_clk_divider(hw); unsigned int div, val; - val = readl(divider->reg) >> divider->shift; + val = clk_readl(divider->reg) >> divider->shift; val &= div_mask(divider); div = _get_div(divider, val); @@ -230,11 +230,11 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { val = div_mask(divider) << (divider->shift + 16); } else { - val = readl(divider->reg); + val = clk_readl(divider->reg); val &= ~(div_mask(divider) << divider->shift); } val |= value << divider->shift; - writel(val, divider->reg); + clk_writel(val, divider->reg); if (divider->lock) spin_unlock_irqrestore(divider->lock, flags); diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 790306e..b7fbd96 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -58,7 +58,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) if (set) reg |= BIT(gate->bit_idx); } else { - reg = readl(gate->reg); + reg = clk_readl(gate->reg); if (set) reg |= BIT(gate->bit_idx); @@ -66,7 +66,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) reg &= ~BIT(gate->bit_idx); } - writel(reg, gate->reg); + clk_writel(reg, gate->reg); if (gate->lock) spin_unlock_irqrestore(gate->lock, flags); @@ -89,7 +89,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw) u32 reg; struct clk_gate *gate = to_clk_gate(hw); - reg = readl(gate->reg); + reg = clk_readl(gate->reg); /* if a set bit disables this clk, flip it before masking */ if (gate->flags & CLK_GATE_SET_TO_DISABLE) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 61c..02ef506 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -42,7 +42,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so * val = 0x4 really means "bit 2, index starts at bit 0" */ - val = readl(mux->reg) >> mux->shift; + val = clk_readl(mux->reg) >> mux->shift; val &= mux->mask; if (mux->table) { @@ -89,11 +89,11 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) if (mux->flags & CLK_MUX_HIWORD_MASK) { val = mux->mask << (mux->shift + 16); } else { - val = readl(mux->reg); + val = clk_readl(mux->reg); val &= ~(mux->mask << mux->shift); } val |= index << mux->shift; - writel(val, mux->reg); + clk_writel(val, mux->reg); if (mux->lock) spin_unlock_irqrestore(mux->lock, flags); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 1ec14a7..c4f7799 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -12,6 +12,7 @@ #define __LINUX_CLK_PROVIDER_H #include +#include #ifdef CONFIG_COMMON_CLK @@ -490,5 +491,21 @@ static inline const char *of_clk_get_parent_name(struct device_node *np, #define of_clk_init(matches) \ { while (0); } #endif /* CONFIG_OF */ + +/* + * wrap access to peripherals in accessor routines + * for improved portability across platforms + */ + +static inline u32 clk_readl(u32 __iomem *reg) +{ + return readl(reg); +} + +static inline void clk_writel(u32 val, u32 __iomem *reg) +{ + writel(val, reg); +} + #endif /* CONFIG_COMMON_CLK */ #endif /* CLK_PROVIDER_H */ -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 02/24] serial: mpc512x: cleanup clock API use
cleanup the clock API use of the UART driver which is shared among the MPC512x and the MPC5200 platforms - get, prepare, and enable the MCLK during port allocation; disable, unprepare and put the MCLK upon port release; hold a reference to the clock over the period of use; check for and propagate enable errors - fix a buffer overflow for clock names with two digit PSC index numbers - stick with the PPC_CLOCK 'psc%d_mclk' name for clock lookup, only switch to a fixed string later after device tree based clock lookup will have become available the omission in the clock handling previously went unnoticed, but will become fatal in the common clock scenario to achieve support for MPC512x which is neutral to MPC5200, the modification was done as follows - introduce "clock alloc" and "clock release" routines in addition to the previous "clock enable/disable" routine in the psc_ops struct - make the clock allocation a part of the port request (resource allocation), and make clock release a part of the port release, such that essential resources get allocated early - just enable/disable the clock from within the .clock() callback without any allocation or preparation as the former implementation did, since this routine is called from within the startup and shutdown callbacks - all of the above remains a NOP for the MPC5200 platform (no callbacks are provided on that platform) - implementation note: the clock gets enabled upon allocation already just in case the clock is not only required for bitrate generation but for register access as well Signed-off-by: Gerhard Sittig --- drivers/tty/serial/mpc52xx_uart.c | 100 ++--- 1 file changed, 83 insertions(+), 17 deletions(-) diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index e1280a2..98a1f43 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -107,6 +107,8 @@ struct psc_ops { unsigned int(*set_baudrate)(struct uart_port *port, struct ktermios *new, struct ktermios *old); + int (*clock_alloc)(struct uart_port *port); + void(*clock_relse)(struct uart_port *port); int (*clock)(struct uart_port *port, int enable); int (*fifoc_init)(void); void(*fifoc_uninit)(void); @@ -616,31 +618,75 @@ static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port) return IRQ_NONE; } -static int mpc512x_psc_clock(struct uart_port *port, int enable) +static struct clk *psc_mclk_clk[MPC52xx_PSC_MAXNUM]; + +/* called from within the .request_port() callback (allocation) */ +static int mpc512x_psc_alloc_clock(struct uart_port *port) { - struct clk *psc_clk; int psc_num; - char clk_name[10]; + char clk_name[16]; + struct clk *clk; + int err; + + psc_num = (port->mapbase & 0xf00) >> 8; + snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); + clk = clk_get(port->dev, clk_name); + if (IS_ERR(clk)) { + dev_err(port->dev, "Failed to get MCLK!\n"); + return PTR_ERR(clk); + } + err = clk_prepare_enable(clk); + if (err) { + dev_err(port->dev, "Failed to enable MCLK!\n"); + clk_put(clk); + return err; + } + psc_mclk_clk[psc_num] = clk; + return 0; +} + +/* called from within the .release_port() callback (release) */ +static void mpc512x_psc_relse_clock(struct uart_port *port) +{ + int psc_num; + struct clk *clk; + + psc_num = (port->mapbase & 0xf00) >> 8; + clk = psc_mclk_clk[psc_num]; + if (clk) { + clk_disable_unprepare(clk); + clk_put(clk); + psc_mclk_clk[psc_num] = NULL; + } +} + +/* implementation of the .clock() callback (enable/disable) */ +static int mpc512x_psc_endis_clock(struct uart_port *port, int enable) +{ + int psc_num; + struct clk *psc_clk; + int ret; if (uart_console(port)) return 0; psc_num = (port->mapbase & 0xf00) >> 8; - snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); - psc_clk = clk_get(port->dev, clk_name); - if (IS_ERR(psc_clk)) { + psc_clk = psc_mclk_clk[psc_num]; + if (!psc_clk) { dev_err(port->dev, "Failed to get PSC clock entry!\n"); return -ENODEV; } - dev_dbg(port->dev, "%s %sable\n", clk_name, enable ? "en" : "dis"); - - if (enable) - clk_enable(psc_clk); - else + dev_dbg(port->dev, "mclk %sable\n", enable ? "en" : "dis"); + if (enable) { + ret = clk_enable(psc_clk); + if (ret) + dev_err(port->dev, "Failed to enable MCLK!\n"); + return ret; +
[PATCH v2 06/24] dts: mpc512x: prepare for preprocessor support
prepare C preprocessor support when processing MPC512x DTS files - switch from DTS syntax to CPP syntax for include specs - create a symlink such that DTS processing can reference includes Signed-off-by: Gerhard Sittig --- arch/powerpc/boot/dts/ac14xx.dts |2 +- arch/powerpc/boot/dts/include/dt-bindings |1 + arch/powerpc/boot/dts/mpc5121ads.dts |2 +- arch/powerpc/boot/dts/pdm360ng.dts|2 +- 4 files changed, 4 insertions(+), 3 deletions(-) create mode 12 arch/powerpc/boot/dts/include/dt-bindings diff --git a/arch/powerpc/boot/dts/ac14xx.dts b/arch/powerpc/boot/dts/ac14xx.dts index a27a460..a543c40 100644 --- a/arch/powerpc/boot/dts/ac14xx.dts +++ b/arch/powerpc/boot/dts/ac14xx.dts @@ -10,7 +10,7 @@ */ -/include/ "mpc5121.dtsi" +#include / { model = "ac14xx"; diff --git a/arch/powerpc/boot/dts/include/dt-bindings b/arch/powerpc/boot/dts/include/dt-bindings new file mode 12 index 000..08c00e4 --- /dev/null +++ b/arch/powerpc/boot/dts/include/dt-bindings @@ -0,0 +1 @@ +../../../../../include/dt-bindings \ No newline at end of file diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts index 7d3cb79..c228a0a 100644 --- a/arch/powerpc/boot/dts/mpc5121ads.dts +++ b/arch/powerpc/boot/dts/mpc5121ads.dts @@ -9,7 +9,7 @@ * option) any later version. */ -/include/ "mpc5121.dtsi" +#include / { model = "mpc5121ads"; diff --git a/arch/powerpc/boot/dts/pdm360ng.dts b/arch/powerpc/boot/dts/pdm360ng.dts index 7433740..871c16d 100644 --- a/arch/powerpc/boot/dts/pdm360ng.dts +++ b/arch/powerpc/boot/dts/pdm360ng.dts @@ -13,7 +13,7 @@ * option) any later version. */ -/include/ "mpc5121.dtsi" +#include / { model = "pdm360ng"; -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 07/24] dts: mpc512x: introduce dt-bindings/clock/ header
introduce a dt-bindings/ header file for MPC512x clocks, providing symbolic identifiers for those SoC clocks which clients will reference from their device tree nodes Signed-off-by: Gerhard Sittig --- include/dt-bindings/clock/mpc512x-clock.h | 59 + 1 file changed, 59 insertions(+) create mode 100644 include/dt-bindings/clock/mpc512x-clock.h diff --git a/include/dt-bindings/clock/mpc512x-clock.h b/include/dt-bindings/clock/mpc512x-clock.h new file mode 100644 index 000..46c560e --- /dev/null +++ b/include/dt-bindings/clock/mpc512x-clock.h @@ -0,0 +1,59 @@ +/* + * This header provides constants for MPC512x clock specs in DT bindings. + * + * Unfortunately the clock number declaration cannot be an enum but + * needs to be a list of #define directives since when referenced from + * within DTS files they need to get resolved "at compile time". + */ + +#ifndef _DT_BINDINGS_CLOCK_MPC512x_CLOCK_H +#define _DT_BINDINGS_CLOCK_MPC512x_CLOCK_H + +#define MPC512x_CLK_DUMMY 0 +#define MPC512x_CLK_REF1 +#define MPC512x_CLK_SYS2 +#define MPC512x_CLK_DIU3 +#define MPC512x_CLK_VIU4 +#define MPC512x_CLK_CSB5 +#define MPC512x_CLK_E300 6 +#define MPC512x_CLK_IPS7 +#define MPC512x_CLK_FEC8 +#define MPC512x_CLK_SATA 9 +#define MPC512x_CLK_PATA 10 +#define MPC512x_CLK_NFC11 +#define MPC512x_CLK_LPC12 +#define MPC512x_CLK_MBX_BUS13 +#define MPC512x_CLK_MBX14 +#define MPC512x_CLK_MBX_3D 15 +#define MPC512x_CLK_AXE16 +#define MPC512x_CLK_USB1 17 +#define MPC512x_CLK_USB2 18 +#define MPC512x_CLK_I2C19 +#define MPC512x_CLK_MSCAN0_MCLK20 +#define MPC512x_CLK_MSCAN1_MCLK21 +#define MPC512x_CLK_MSCAN2_MCLK22 +#define MPC512x_CLK_MSCAN3_MCLK23 +#define MPC512x_CLK_SDHC 24 +#define MPC512x_CLK_PCI25 +#define MPC512x_CLK_PSC_MCLK_IN26 +#define MPC512x_CLK_SPDIF_TX 27 +#define MPC512x_CLK_SPDIF_RX 28 +#define MPC512x_CLK_SPDIF_MCLK 29 +#define MPC512x_CLK_AC97 30 +#define MPC512x_CLK_PSC0_MCLK 31 +#define MPC512x_CLK_PSC1_MCLK 32 +#define MPC512x_CLK_PSC2_MCLK 33 +#define MPC512x_CLK_PSC3_MCLK 34 +#define MPC512x_CLK_PSC4_MCLK 35 +#define MPC512x_CLK_PSC5_MCLK 36 +#define MPC512x_CLK_PSC6_MCLK 37 +#define MPC512x_CLK_PSC7_MCLK 38 +#define MPC512x_CLK_PSC8_MCLK 39 +#define MPC512x_CLK_PSC9_MCLK 40 +#define MPC512x_CLK_PSC10_MCLK 41 +#define MPC512x_CLK_PSC11_MCLK 42 +#define MPC512x_CLK_PSC_FIFO 43 + +#define MPC512x_CLK_LAST_PUBLIC43 + +#endif -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 08/24] dts: mpc512x: add clock related device tree specs
this addresses the clock driver aka provider's side of clocks - prepare for future '<&clks ID>' phandle references for device tree based clock lookup in client drivers - introduce a 'clocks' subtree with an 'osc' node for the crystal or oscillator SoC input (fixed frequency) - provide default values with 33MHz oscillator frequency in the common include (the 66MHz IPS bus already was there), add override values for the ifm AC14xx board which deviates from the reference design (25MHz xtal, 80MHz IPS bus) Signed-off-by: Gerhard Sittig --- arch/powerpc/boot/dts/ac14xx.dts |7 +++ arch/powerpc/boot/dts/mpc5121.dtsi | 15 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/ac14xx.dts b/arch/powerpc/boot/dts/ac14xx.dts index a543c40..a1b8837 100644 --- a/arch/powerpc/boot/dts/ac14xx.dts +++ b/arch/powerpc/boot/dts/ac14xx.dts @@ -139,7 +139,14 @@ }; }; + clocks { + osc { + clock-frequency = <2500>; + }; + }; + soc@8000 { + bus-frequency = <8000>; /* 80 MHz ips bus */ clock@f00 { compatible = "fsl,mpc5121rev2-clock", "fsl,mpc5121-clock"; diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index bd14c00..8f4cba0 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi @@ -9,6 +9,8 @@ * option) any later version. */ +#include + /dts-v1/; / { @@ -73,6 +75,16 @@ ranges = <0x0 0x0 0xfc00 0x0400>; }; + clocks { + #address-cells = <1>; + #size-cells = <0>; + + osc { + compatible = "fsl,mpc512x-osc", "fixed-clock"; + clock-frequency = <3300>; + }; + }; + soc@8000 { compatible = "fsl,mpc5121-immr"; #address-cells = <1>; @@ -118,9 +130,10 @@ }; /* Clock control */ - clock@f00 { + clks: clock@f00 { compatible = "fsl,mpc5121-clock"; reg = <0xf00 0x100>; + #clock-cells = <1>; }; /* Power Management Controller */ -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 09/24] clk: mpc512x: introduce COMMON_CLK for MPC512x
this change introduces a clock infrastructure implementation for the MPC512x PowerPC platform which follows the COMMON_CLK approach and uses common clock drivers shared with other platforms this driver implements the publicly announced set of clocks (which can get referenced by means of symbolic identifiers from the dt-bindings header file), as well as generates additional 'struct clk' items where the SoC hardware cannot easily get mapped to the common primitives of the clock API, or requires "intermediate" clock nodes to represent clocks that have both gates and dividers the previous PPC_CLOCK implementation is kept in place and resides in parallel to the common clock implementation for test and comparison during migration, a compile time option picks one of the two alternatives (Kconfig switch, common clock used by default) since not all drivers for peripherals were adjusted yet to properly allocate and release their clock items, this platform clock driver implementation pre-enables some of the clock items to not break peripheral drivers during migration -- these clock pre-enable workarounds will get removed as peripheral drivers get adjusted to provide clock names which the serial communication drivers are using and where the PSC index number is encoded into, clkdev registration is done to not break these peripheral drivers -- this workaround will get removed as these drivers get adjusted after device tree based clock lookup has become available Signed-off-by: Gerhard Sittig --- arch/powerpc/platforms/512x/Kconfig | 14 +- arch/powerpc/platforms/512x/Makefile |4 +- arch/powerpc/platforms/512x/clock-commonclk.c | 778 + include/linux/clk-provider.h | 16 + 4 files changed, 810 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/platforms/512x/clock-commonclk.c diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index fc9c1cb..c5fcdd0 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -1,9 +1,21 @@ +config MPC512x_COMMON_CLK + bool "MPC512x platform uses COMMON_CLK" + default y + depends on PPC_MPC512x + help + This option is only here to support tests and comparison + during development and migration. This option will get + removed after the COMMON_CLK support for MPC512x has become + fully operational and all drivers were adjusted to explicitly + acquire their required clocks. + config PPC_MPC512x bool "512x-based boards" depends on 6xx select FSL_SOC select IPIC - select PPC_CLOCK + select PPC_CLOCK if !MPC512x_COMMON_CLK + select COMMON_CLK if MPC512x_COMMON_CLK select PPC_PCI_CHOICE select FSL_PCI if PCI select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 72fb934..1e05f9d 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile @@ -1,7 +1,9 @@ # # Makefile for the Freescale PowerPC 512x linux kernel. # -obj-y += clock.o mpc512x_shared.o +obj-$(CONFIG_PPC_CLOCK)+= clock.o +obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o +obj-y += mpc512x_shared.o obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o obj-$(CONFIG_PDM360NG) += pdm360ng.o diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c new file mode 100644 index 000..6627957 --- /dev/null +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -0,0 +1,778 @@ +/* + * Copyright (C) 2013 DENX Software Engineering + * + * Gerhard Sittig, + * + * common clock driver support for the MPC512x platform + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mpc512x.h" /* our public mpc5121_clk_init() API */ + +/* helpers to keep the MCLK intermediates "somewhere" in our table */ +enum { + MCLK_IDX_MUX0, + MCLK_IDX_EN0, + MCLK_IDX_DIV0, + MCLK_IDX_MUX1, + MCLK_MAX_IDX, +}; + +#define NR_PSCS12 +#define NR_MSCANS 4 +#define NR_SPDIFS 1 +#define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS) + +/* extend the public set of clocks by adding internal slots for management */ +enum { + /* arrange for adjacent numbers after the public set */ + MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC, + /* clocks which aren't announced to
[PATCH v2 10/24] dts: mpc512x: add clock specs for client lookups
this addresses the client side of device tree based clock lookups: add clock specifiers to the mbx, nfc, mscan, sdhc, i2c, axe, diu, viu, mdio, fec, usb, pata, psc, psc fifo, and pci nodes in the shared mpc5121.dtsi include these specs map 'clock-names' encoded in drivers to their respective 'struct clk' items in the platform's clock driver; some drivers still need to learn how to lookup OF clocks, other drivers will transparently probe successfully on MPC512x as well (sdhc) few 'clock-names' (nfc, viu) use strings that are encoded in their respective drivers to keep up compatibility, an alternative approach would be to register clkdev items in the platform's clock driver for the migration period Signed-off-by: Gerhard Sittig --- arch/powerpc/boot/dts/mpc5121.dtsi | 79 1 file changed, 79 insertions(+) diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index 8f4cba0..983da9c 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi @@ -51,6 +51,10 @@ compatible = "fsl,mpc5121-mbx"; reg = <0x2000 0x4000>; interrupts = <66 0x8>; + clocks = <&clks MPC512x_CLK_MBX_BUS>, +<&clks MPC512x_CLK_MBX_3D>, +<&clks MPC512x_CLK_MBX>; + clock-names = "mbx-bus", "mbx-3d", "mbx"; }; sram@3000 { @@ -64,6 +68,8 @@ interrupts = <6 8>; #address-cells = <1>; #size-cells = <1>; + clocks = <&clks MPC512x_CLK_NFC>; + clock-names = "nfc_clk";/* backwards compat */ }; localbus@8020 { @@ -153,12 +159,22 @@ compatible = "fsl,mpc5121-mscan"; reg = <0x1300 0x80>; interrupts = <12 0x8>; + clocks = <&clks MPC512x_CLK_IPS>, +<&clks MPC512x_CLK_SYS>, +<&clks MPC512x_CLK_REF>, +<&clks MPC512x_CLK_MSCAN0_MCLK>; + clock-names = "ips", "sys", "ref", "mclk"; }; can@1380 { compatible = "fsl,mpc5121-mscan"; reg = <0x1380 0x80>; interrupts = <13 0x8>; + clocks = <&clks MPC512x_CLK_IPS>, +<&clks MPC512x_CLK_SYS>, +<&clks MPC512x_CLK_REF>, +<&clks MPC512x_CLK_MSCAN1_MCLK>; + clock-names = "ips", "sys", "ref", "mclk"; }; sdhc@1500 { @@ -167,6 +183,9 @@ interrupts = <8 0x8>; dmas = <&dma0 30>; dma-names = "rx-tx"; + clocks = <&clks MPC512x_CLK_IPS>, +<&clks MPC512x_CLK_SDHC>; + clock-names = "ipg", "per"; }; i2c@1700 { @@ -175,6 +194,8 @@ compatible = "fsl,mpc5121-i2c", "fsl-i2c"; reg = <0x1700 0x20>; interrupts = <9 0x8>; + clocks = <&clks MPC512x_CLK_I2C>; + clock-names = "per"; }; i2c@1720 { @@ -183,6 +204,8 @@ compatible = "fsl,mpc5121-i2c", "fsl-i2c"; reg = <0x1720 0x20>; interrupts = <10 0x8>; + clocks = <&clks MPC512x_CLK_I2C>; + clock-names = "per"; }; i2c@1740 { @@ -191,6 +214,8 @@ compatible = "fsl,mpc5121-i2c", "fsl-i2c"; reg = <0x1740 0x20>; interrupts = <11 0x8>; + clocks = <&clks MPC512x_CLK_I2C>; + clock-names = "per"; }; i2ccontrol@1760 { @@ -202,30 +227,46 @@ compatible = "fsl,mpc5121-axe"; reg = <0x2000 0x100>; interrupts = <42 0x8>; + clocks = <&clks MPC512x_CLK_AXE>; + clock-names = "per"; }; display@2100 { compatible = "fsl,mpc5121-diu"; reg = <0x2100 0x100>; interrupts = <64 0x8>; + clocks = <&clks MPC512x_CLK_DIU>; + clock-names = "per"; }; can@2300 { compatible = "fsl,mpc5121-mscan"; reg = <0x2300 0x80>; interrupts = <90 0x8>; + clocks = <&clks MPC512x_CLK_IPS>, +
[PATCH v2 11/24] spi: mpc512x: remove now obsolete clock lookup name
after device tree based clock lookup became available, the peripheral driver need no longer construct clock names which include the PSC index, remove the "psc%d_mclk" template and unconditionally use "mclk" Signed-off-by: Gerhard Sittig --- drivers/spi/spi-mpc512x-psc.c |6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 7a32373..b04f094 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -474,8 +474,6 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, struct spi_master *master; int ret; void *tempp; - int psc_num; - char clk_name[16]; master = spi_alloc_master(dev, sizeof *mps); if (master == NULL) @@ -518,9 +516,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, goto free_master; init_completion(&mps->txisrdone); - psc_num = master->bus_num; - snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); - mps->clk_mclk = clk_get(dev, clk_name); + mps->clk_mclk = clk_get(dev, "mclk"); if (IS_ERR(mps->clk_mclk)) goto free_irq; ret = clk_prepare_enable(mps->clk_mclk); -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 12/24] serial: mpc512x: remove now obsolete clock lookup name
after device tree based clock lookup became available, the peripheral driver need no longer construct clock names which include the PSC index, remove the "psc%d_mclk" template and unconditionally use "mclk" Signed-off-by: Gerhard Sittig --- drivers/tty/serial/mpc52xx_uart.c |8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 98a1f43..8643dcf 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -623,14 +623,11 @@ static struct clk *psc_mclk_clk[MPC52xx_PSC_MAXNUM]; /* called from within the .request_port() callback (allocation) */ static int mpc512x_psc_alloc_clock(struct uart_port *port) { - int psc_num; - char clk_name[16]; struct clk *clk; int err; + int psc_num; - psc_num = (port->mapbase & 0xf00) >> 8; - snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); - clk = clk_get(port->dev, clk_name); + clk = clk_get(port->dev, "mclk"); if (IS_ERR(clk)) { dev_err(port->dev, "Failed to get MCLK!\n"); return PTR_ERR(clk); @@ -641,6 +638,7 @@ static int mpc512x_psc_alloc_clock(struct uart_port *port) clk_put(clk); return err; } + psc_num = (port->mapbase & 0xf00) >> 8; psc_mclk_clk[psc_num] = clk; return 0; } -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 13/24] clk: mpc512x: remove now obsolete clkdev registration
after the peripheral drivers for UART and SPI mode (both using the PSC controller) got converted to device tree based clock lookups, the platform clock driver need no longer provide the "psc%d_mclk" name which depends on the PSC index number -- remove the clk_register_clkdev() call Signed-off-by: Gerhard Sittig --- arch/powerpc/platforms/512x/clock-commonclk.c | 12 1 file changed, 12 deletions(-) diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index 6627957..b822469 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include @@ -529,17 +528,6 @@ static void mpc512x_clk_setup_mclk(struct mclk_setup_data *entry) entry->name_mclk, entry->name_mux1, 1, 1); } - - /* -* without this "clock device" registration, "simple" lookups in -* the SPI master initialization and serial port setup will fail -* -* those drivers need to get adjusted to lookup their required -* clocks from device tree specs, and device tree nodes need to -* provide the clock specs, before this clkdev registration -* becomes obsolete -*/ - clk_register_clkdev(clks[clks_idx_pub], entry->name_mclk, NULL); } static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_t count) -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 14/24] serial: mpc512x: setup the PSC FIFO clock as well
prepare and enable the FIFO clock upon PSC FIFO initialization, disable and unprepare the FIFO clock upon PSC FIFO uninitialization, remove the pre-enable workaround from the platform's clock driver Signed-off-by: Gerhard Sittig --- arch/powerpc/platforms/512x/clock-commonclk.c |2 -- drivers/tty/serial/mpc52xx_uart.c | 39 + 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index b822469..99d197d 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -689,8 +689,6 @@ static void mpc512x_clk_setup_clock_tree(int busfreq) clk_prepare_enable(clks[MPC512x_CLK_MEM]); /* SRAM */ clk_prepare_enable(clks[MPC512x_CLK_IPS]); /* SoC periph */ clk_prepare_enable(clks[MPC512x_CLK_LPC]); /* boot media */ - /* some are required yet no dependencies were declared */ - clk_prepare_enable(clks[MPC512x_CLK_PSC_FIFO]); /* some are not yet acquired by their respective drivers */ clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */ clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */ diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 8643dcf..3fdadf9 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -421,6 +421,7 @@ struct psc_fifoc { static struct psc_fifoc __iomem *psc_fifoc; static unsigned int psc_fifoc_irq; +static struct clk *psc_fifoc_clk; static void mpc512x_psc_fifo_init(struct uart_port *port) { @@ -574,30 +575,56 @@ static int __init mpc512x_psc_fifoc_init(void) "fsl,mpc5121-psc-fifo"); if (!np) { pr_err("%s: Can't find FIFOC node\n", __func__); - return -ENODEV; + goto out_err; + } + + psc_fifoc_clk = of_clk_get_by_name(np, "per"); + if (IS_ERR(psc_fifoc_clk)) { + pr_err("%s: Can't lookup FIFO clock\n", __func__); + goto out_ofnode_put; + } + if (clk_prepare_enable(psc_fifoc_clk)) { + pr_err("%s: Can't enable FIFO clock\n", __func__); + goto out_clk_put; } psc_fifoc = of_iomap(np, 0); if (!psc_fifoc) { pr_err("%s: Can't map FIFOC\n", __func__); - of_node_put(np); - return -ENODEV; + goto out_clk_disable; } psc_fifoc_irq = irq_of_parse_and_map(np, 0); - of_node_put(np); if (psc_fifoc_irq == 0) { pr_err("%s: Can't get FIFOC irq\n", __func__); - iounmap(psc_fifoc); - return -ENODEV; + goto out_unmap; } + of_node_put(np); return 0; + +out_unmap: + iounmap(psc_fifoc); +out_clk_disable: + clk_disable_unprepare(psc_fifoc_clk); +out_clk_put: + clk_put(psc_fifoc_clk); +out_ofnode_put: + of_node_put(np); +out_err: + return -ENODEV; } static void __exit mpc512x_psc_fifoc_uninit(void) { iounmap(psc_fifoc); + + /* disable the clock, errors are not fatal */ + if (psc_fifoc_clk && !IS_ERR(psc_fifoc_clk)) { + clk_disable_unprepare(psc_fifoc_clk); + clk_put(psc_fifoc_clk); + psc_fifoc_clk = NULL; + } } /* 512x specific interrupt handler. The caller holds the port lock */ -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v1 05/24] clk: wrap I/O access for improved portability
On Thu, 18 Jul 2013, Russell King - ARM Linux wrote: > 1. clk_get() and clk_put() are NOT part of the common clock API. >They're separate - they're part of the clk API, and the infrastructure >behind that is clkdev, which is a separately owned thing (by me.) > > 2. The "contract" of the clk API is defined by the clk API, not by some >random implementation like the common clock API. The clk API is >maintained by myself, and is described in include/linux/clk.h > > 3. clk_prepare() and clk_unprepare() are functions MUST only be called >from contexts where sleeping is permitted. These functions MAY sleep >for whatever reason they require to, and as long as they require to. >(This is the whole reason these two functions were created in the >first place.) > > 4. clk_enable() and clk_disable() MAY be called from any context, but >MUST never sleep. If you need to talk over a non-atomic bus for these, >then these functions should be no-ops, and the code which does that >must be executed from the clk_prepare()/clk_unprepare() operations. Could the above be included in some form in Documentation/clk.txt (this is likely one of the first location people look for information) and elsewhere if appropriate please? A *lot* of people are confused by the prepare-enable-disable-unprepare sequence and when I try to find some rational for the prepare/enable split I can only direct them to mail archive posts since this is nowhere to be found in the kernel. The comments in include/linux/clk.h, while correct, are very terse and don't provide any insight to the reason why there is a split in the API. The content of Documentation/clk.txt does refer to prepare and enable (and their counterparts) but again doesn't provide any clue about the reason for their existence. Since there've been several good posts with usage example now buried into list archives, I think this would go a long way helping people get it right if those were part of the kernel documentation as well. Nicolas ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 13/76] perf tools: Make Power7 events available for perf
From: Runzhen Wang Power7 supports over 530 different perf events but only a small subset of these can be specified by name, for the remaining events, we must specify them by their raw code: perf stat -e r2003c This patch makes all the POWER7 events available in sysfs. So we can instead specify these as: perf stat -e 'cpu/PM_CMPLU_STALL_DFU/' where PM_CMPLU_STALL_DFU is the r2003c in previous example. Before this patch is applied, the size of power7-pmu.o is: $ size arch/powerpc/perf/power7-pmu.o textdata bss dec hex filename 30732720 0579316a1 arch/powerpc/perf/power7-pmu.o and after the patch is applied, it is: $ size arch/powerpc/perf/power7-pmu.o textdata bss dec hex filename 15950 31112 0 47062b7d6 arch/powerpc/perf/power7-pmu.o For the run time overhead, I use two scripts, one is "event_name.sh", which contains 50 event names, it looks like: # ./perf record -e 'cpu/PM_CMPLU_STALL_DFU/' -e . /bin/sleep 1 the other one is named "event_code.sh" which use corresponding events raw code instead of events names, it looks like: # ./perf record -e r2003c -e .. /bin/sleep 1 below is the result. Using events name: [root@localhost perf]# time ./event_name.sh [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.002 MB perf.data (~102 samples) ] real0m1.192s user0m0.028s sys 0m0.106s Using events raw code: [root@localhost perf]# time ./event_code.sh [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.003 MB perf.data (~112 samples) ] real0m1.198s user0m0.028s sys 0m0.105s Signed-off-by: Runzhen Wang Acked-by: Michael Ellerman Cc: icyco...@gmail.com Cc: linuxppc-dev@lists.ozlabs.org Cc: Michael Ellerman Cc: Paul Mackerras Cc: Runzhen Wang Cc: Sukadev Bhattiprolu Cc: Xiao Guangrong Link: http://lkml.kernel.org/r/1372407297-6996-3-git-send-email-runz...@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- arch/powerpc/include/asm/perf_event_server.h | 4 +- arch/powerpc/perf/power7-events-list.h | 548 +++ arch/powerpc/perf/power7-pmu.c | 148 ++-- 3 files changed, 582 insertions(+), 118 deletions(-) create mode 100644 arch/powerpc/perf/power7-events-list.h diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index f265049..d9270d8 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h @@ -136,11 +136,11 @@ extern ssize_t power_events_sysfs_show(struct device *dev, #defineEVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr #defineEVENT_ATTR(_name, _id, _suffix) \ - PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_PM_##_id,\ + PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_##_id, \ power_events_sysfs_show) #defineGENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) #defineGENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) -#definePOWER_EVENT_ATTR(_name, _id)EVENT_ATTR(PM_##_name, _id, _p) +#definePOWER_EVENT_ATTR(_name, _id)EVENT_ATTR(_name, _id, _p) #definePOWER_EVENT_PTR(_id)EVENT_PTR(_id, _p) diff --git a/arch/powerpc/perf/power7-events-list.h b/arch/powerpc/perf/power7-events-list.h new file mode 100644 index 000..687790a --- /dev/null +++ b/arch/powerpc/perf/power7-events-list.h @@ -0,0 +1,548 @@ +/* + * Performance counter support for POWER7 processors. + * + * Copyright 2013 Runzhen Wang, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +EVENT(PM_IC_DEMAND_L2_BR_ALL, 0x04898) +EVENT(PM_GCT_UTIL_7_TO_10_SLOTS, 0x020a0) +EVENT(PM_PMC2_SAVED, 0x10022) +EVENT(PM_CMPLU_STALL_DFU, 0x2003c) +EVENT(PM_VSU0_16FLOP, 0x0a0a4) +EVENT(PM_MRK_LSU_DERAT_MISS, 0x3d05a) +EVENT(PM_MRK_ST_CMPL, 0x10034) +EVENT(PM_NEST_PAIR3_ADD, 0x40881) +EVENT(PM_L2_ST_DISP, 0x46180) +EVENT(PM_L2_CASTOUT_MOD, 0x16180) +EVENT(PM_ISEG,0x020a4) +EVENT(PM_MRK_INST_TIMEO, 0x40034) +EVENT(PM_L2_RCST_DISP_FAIL_ADDR, 0x36282) +EVENT(PM_LSU1_DC_PREF_STREAM_CONFIRM, 0x0d0b6) +EVENT(PM_IERAT_WR_64K,0x040be) +EVENT(PM_MRK_DTLB_MISS_16M, 0x4d05e) +EVENT(PM_IERAT_MISS, 0x100f6) +EVENT(PM_MRK_PTEG_FROM_LME
[GIT PULL 00/76] perf/core improvements and fixes
From: Arnaldo Carvalho de Melo Hi Ingo, Please consider pulling. There was a long delay in processing patches related to my vacations that took longer than antecipated to being addressed. With the recent acme/perf/urgent merge and this one I get closer to processing the resulting long backlog. There are still many patches to process, which I will be working on as time permits in the next days and weeks. Thanks, - Arnaldo The following changes since commit 67516844625f45f0ce148a01c27bf41f591872b2: perf: Remove the 'match' callback for auxiliary events processing (2013-07-12 13:50:36 +0200) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux tags/perf-core-for-mingo for you to fetch changes up to 2a08c3ec4f7d6058a450d2d4bc6e366955872707: perf header: Recognize version number for perf data file (2013-07-17 17:04:00 -0300) perf/core improvements and fixes: . Add missing 'finished_round' event forwarding in 'perf inject', from Adrian Hunter. . Assorted tidy ups, from Adrian Hunter. . Fall back to sysfs event names when parsing fails, from Andi Kleen. . List pmu events in perf list, from Andi Kleen. . Cleanup some memory allocation/freeing uses, from David Ahern. . Add option to collapse undesired parts of call graph, from Greg Price. . Prep work for multi perf data file storage, from Jiri Olsa. . Add support for more than two files comparision in 'perf diff', from Jiri Olsa . A few more 'perf test' improvements, from Jiri Olsa . libtraceevent cleanups, from Namhyung Kim. . Remove odd build stall in 'perf sched' by moving a large struct initialization from a local variable to a global one, from Namhyung Kim. . Add support for callchains in the gtk UI, from Namhyung Kim. . Do not apply symfs for an absolute vmlinux path, fix from Namhyung Kim. . Use default include path notation for libtraceevent, from Robert Richter. . Fix 'make tools/perf', from Robert Richter. . Make Power7 events available, from Runzhen Wang. . Add --objdump option to 'perf top', from Sukadev Bhattiprolu. Signed-off-by: Arnaldo Carvalho de Melo Adrian Hunter (7): perf inject: Remove unused parameter perf tools: Fix missing tool parameter perf inject: Add missing 'finished_round' perf tools: Add const specifier to perf_pmu__find name parameter perf evlist: Tidy duplicated munmap code perf tools: Validate perf event header size perf tools: struct thread has a tid not a pid Andi Kleen (2): perf tools: Default to cpu// for events v5 perf list: List kernel supplied event aliases David Ahern (5): perf tools: Add methods for setting/retrieving priv element of thread struct perf evlist: Fix use of uninitialized variable perf tools: Don't free list head in parse_events__free_terms perf tests: Make terms a stack variable in test_term perf parse events: Demystify memory allocations Greg Price (1): perf report/top: Add option to collapse undesired parts of call graph Jiri Olsa (30): perf tools: Remove cwd from perf_session struct perf tests: Omit end of the symbol check failure for test 1 perf tests: Make TEST_ASSERT_VAL global perf tools: Remove callchain_cursor_reset call perf tools: Do not elide parent symbol column perf report: Fix perf_session__delete removal perf tools: Add struct perf_hpp_fmt into hpp callbacks perf tools: Centralize default columns init in perf_hpp__init perf diff: Introducing diff_data object to hold files perf diff: Switching the base hists to be pairs head perf hists: Marking dummy hists entries perf diff: Display data file info ahead of the diff output perf diff: Move diff related columns into diff command perf diff: Move columns into struct data__file perf diff: Change diff command to work over multiple data files perf diff: Update perf diff documentation for multiple data comparison perf diff: Making compute functions static perf diff: Add generic order option for compute sorting perf tools: Move hist_entry__period_snprintf into stdio code perf timechart: Use traceevent lib event-parse.h include perf timechart: Remove event types framework only user perf tools: Remove event types from perf data file perf record: Remove event types pushing perf tools: Remove event types framework completely perf tests: Check proper prev_state size for sched_switch tp perf session: Use session->fd instead of passing fd as argument perf header: Remove data_offset seek as it's not needed perf header: Remove attr_offset from perf_header perf header: Introduce feat_offset into perf_header perf header: Recognize version number f
[PATCH v2 15/24] net: can: mscan: add a comment on reg to idx mapping
add a comment about the magic of deriving an MSCAN component index from the peripheral's physical address / register offset Signed-off-by: Gerhard Sittig --- drivers/net/can/mscan/mpc5xxx_can.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 5b0ee8e..bc422ba 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -148,7 +148,10 @@ static u32 mpc512x_can_get_clock(struct platform_device *ofdev, goto exit_put; } - /* Determine the MSCAN device index from the physical address */ + /* Determine the MSCAN device index from the peripheral's +* physical address. Register address offsets against the +* IMMR base are: 0x1300, 0x1380, 0x2300, 0x2380 +*/ pval = of_get_property(ofdev->dev.of_node, "reg", &plen); BUG_ON(!pval || plen < sizeof(*pval)); clockidx = (*pval & 0x80) ? 1 : 0; -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 17/24] powerpc/mpc512x: improve DIU related clock setup
adapt the DIU clock initialization to the COMMON_CLK approach: device tree based clock lookup, prepare and unprepare for clocks, work with frequencies not dividers, call the appropriate clk_*() routines and don't access CCM registers, remove the pre-enable workaround in the platform's clock driver the "best clock" determination now completely relies on the platform's clock driver to pick a frequency close to what the caller requests, and merely checks whether the desired frequency was met (is acceptable since it meets the tolerance of the monitor) -- this approach shall succeed upon first try in the usual case, will test a few less desirable yet acceptable frequencies in edge cases, and will fallback to "best effort" if none of the previously tried frequencies pass the test Signed-off-by: Gerhard Sittig --- arch/powerpc/platforms/512x/clock-commonclk.c |1 - arch/powerpc/platforms/512x/mpc512x_shared.c | 165 + 2 files changed, 88 insertions(+), 78 deletions(-) diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index 99d197d..b8963b7 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -692,7 +692,6 @@ static void mpc512x_clk_setup_clock_tree(int busfreq) /* some are not yet acquired by their respective drivers */ clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */ clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */ - clk_prepare_enable(clks[MPC512x_CLK_DIU]); /* display */ clk_prepare_enable(clks[MPC512x_CLK_I2C]); /* * some have their individual clock subtree with separate clock diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index a82a41b..3381eea 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -12,6 +12,7 @@ * (at your option) any later version. */ +#include #include #include #include @@ -70,98 +71,108 @@ struct fsl_diu_shared_fb { boolin_use; }; -#define DIU_DIV_MASK 0x00ff +/* receives a pixel clock spec in pico seconds, adjusts the DIU clock rate */ void mpc512x_set_pixel_clock(unsigned int pixclock) { - unsigned long bestval, bestfreq, speed, busfreq; - unsigned long minpixclock, maxpixclock, pixval; - struct mpc512x_ccm __iomem *ccm; struct device_node *np; - u32 temp; - long err; - int i; + struct clk *clk_diu; + unsigned long epsilon, minpixclock, maxpixclock; + unsigned long offset, want, got, delta; - np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); + /* lookup and enable the DIU clock */ + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu"); if (!np) { - pr_err("Can't find clock control module.\n"); + pr_err("Could not find DIU device tree node.\n"); return; } - - ccm = of_iomap(np, 0); + clk_diu = of_clk_get_by_name(np, "per"); of_node_put(np); - if (!ccm) { - pr_err("Can't map clock control module reg.\n"); + if (IS_ERR(clk_diu)) { + pr_err("Could not lookup DIU clock.\n"); return; } - - np = of_find_node_by_type(NULL, "cpu"); - if (np) { - const unsigned int *prop = - of_get_property(np, "bus-frequency", NULL); - - of_node_put(np); - if (prop) { - busfreq = *prop; - } else { - pr_err("Can't get bus-frequency property\n"); - return; - } - } else { - pr_err("Can't find 'cpu' node.\n"); + if (clk_prepare_enable(clk_diu)) { + pr_err("Could not enable DIU clock.\n"); return; } - /* Pixel Clock configuration */ - pr_debug("DIU: Bus Frequency = %lu\n", busfreq); - speed = busfreq * 4; /* DIU_DIV ratio is 4 * CSB_CLK / DIU_CLK */ - - /* Calculate the pixel clock with the smallest error */ - /* calculate the following in steps to avoid overflow */ - pr_debug("DIU pixclock in ps - %d\n", pixclock); - temp = (10 / pixclock) * 1000; - pixclock = temp; - pr_debug("DIU pixclock freq - %u\n", pixclock); - - temp = temp / 20; /* pixclock * 0.05 */ - pr_debug("deviation = %d\n", temp); - minpixclock = pixclock - temp; - maxpixclock = pixclock + temp; - pr_debug("DIU minpixclock - %lu\n", minpixclock); - pr_debug("DIU maxpixclock - %lu\n", maxpixclock); - pixval = speed/pixclock; - pr_debug("DIU pixval = %lu\n", pixval); - - err = LONG_MAX; - bestval = pixval; - pr_debug("DIU bestval = %lu\n", bestval);
[PATCH v2 16/24] net: can: mscan: make mpc512x code use common clock
extend the mscan(4) driver with alternative support for the COMMON_CLK approach which is an option in the MPC512x platform, keep the existing clock support implementation in place since the driver is shared with other MPC5xxx SoCs which don't have common clock support one byproduct of this change is that the CAN driver no longer needs to access the SoC's clock control registers, which shall be the domain of the platform's clock driver Signed-off-by: Gerhard Sittig --- drivers/net/can/mscan/mpc5xxx_can.c | 139 +++ 1 file changed, 139 insertions(+) diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index bc422ba..dd26ab6 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -108,6 +108,143 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, #endif /* CONFIG_PPC_MPC52xx */ #ifdef CONFIG_PPC_MPC512x + +#if IS_ENABLED(CONFIG_COMMON_CLK) + +static u32 mpc512x_can_get_clock(struct platform_device *ofdev, +const char *clock_source, int *mscan_clksrc) +{ + struct device_node *np; + u32 clockdiv; + enum { + CLK_FROM_AUTO, + CLK_FROM_IPS, + CLK_FROM_SYS, + CLK_FROM_REF, + } clk_from; + struct clk *clk_in, *clk_can; + unsigned long freq_calc; + + /* the caller passed in the clock source spec that was read from +* the device tree, get the optional clock divider as well +*/ + np = ofdev->dev.of_node; + clockdiv = 1; + of_property_read_u32(np, "fsl,mscan-clock-divider", &clockdiv); + dev_dbg(&ofdev->dev, "device tree specs: clk src[%s] div[%d]\n", + clock_source ? clock_source : "", clockdiv); + + /* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to +* get set, and the 'ips' clock is the input to the MSCAN +* component +* +* for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC] +* bit needs to get cleared, an optional clock-divider may have +* been specified (the default value is 1), the appropriate +* MSCAN related MCLK is the input to the MSCAN component +* +* in the absence of a clock-source spec, first an optimal clock +* gets determined based on the 'sys' clock, if that fails the +* 'ref' clock is used +*/ + clk_from = CLK_FROM_AUTO; + if (clock_source) { + /* interpret the device tree's spec for the clock source */ + if (!strcmp(clock_source, "ip")) + clk_from = CLK_FROM_IPS; + else if (!strcmp(clock_source, "sys")) + clk_from = CLK_FROM_SYS; + else if (!strcmp(clock_source, "ref")) + clk_from = CLK_FROM_REF; + else + goto err_invalid; + dev_dbg(&ofdev->dev, "got a clk source spec[%d]\n", clk_from); + } + if (clk_from == CLK_FROM_AUTO) { + /* no spec so far, try the 'sys' clock; round to the +* next MHz and see if we can get a multiple of 16MHz +*/ + dev_dbg(&ofdev->dev, "no clk source spec, trying SYS\n"); + clk_in = clk_get(&ofdev->dev, "sys"); + if (IS_ERR(clk_in)) + goto err_notavail; + freq_calc = clk_get_rate(clk_in); + freq_calc += 49; + freq_calc /= 100; + freq_calc *= 100; + if ((freq_calc % 1600) == 0) { + clk_from = CLK_FROM_SYS; + clockdiv = freq_calc / 1600; + dev_dbg(&ofdev->dev, + "clk fit, sys[%lu] div[%d] freq[%lu]\n", + freq_calc, clockdiv, freq_calc / clockdiv); + } + } + if (clk_from == CLK_FROM_AUTO) { + /* no spec so far, use the 'ref' clock */ + dev_dbg(&ofdev->dev, "no clk source spec, trying REF\n"); + clk_in = clk_get(&ofdev->dev, "ref"); + if (IS_ERR(clk_in)) + goto err_notavail; + clk_from = CLK_FROM_REF; + freq_calc = clk_get_rate(clk_in); + dev_dbg(&ofdev->dev, + "clk fit, ref[%lu] (no div) freq[%lu]\n", + freq_calc, freq_calc); + } + + /* select IPS or MCLK as the MSCAN input (returned to the caller), +* setup the MCLK mux source and rate if applicable, apply the +* optionally specified or derived above divider, and determine +* the actual resulting clock rate to return to the caller +*/ + switch (clk_from) { + case CLK_FROM_IPS: + clk_can = clk_get(&ofdev->dev, "ips"); +
[PATCH v2 19/24] USB: fsl-mph-dr-of: OF clock lookup, prepare and enable
device tree based clock lookup in the MPC512x initialization (lookup 'per' for register access), add error check in the clock setup, must prepare clocks before they can get enabled, unprepare after disable Signed-off-by: Gerhard Sittig --- drivers/usb/host/fsl-mph-dr-of.c | 24 +--- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 11e0b79..eb564f3 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -260,25 +260,19 @@ int fsl_usb2_mpc5121_init(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct clk *clk; - char clk_name[10]; - int base, clk_num; - - base = pdev->resource->start & 0xf000; - if (base == 0x3000) - clk_num = 1; - else if (base == 0x4000) - clk_num = 2; - else - return -ENODEV; + int err; - snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num); - clk = clk_get(&pdev->dev, clk_name); + clk = clk_get(&pdev->dev, "per"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed to get clk\n"); return PTR_ERR(clk); } - - clk_enable(clk); + err = clk_prepare_enable(clk); + if (err) { + dev_err(&pdev->dev, "failed to enable clk\n"); + clk_put(clk); + return err; + } pdata->clk = clk; if (pdata->phy_mode == FSL_USB2_PHY_UTMI_WIDE) { @@ -303,7 +297,7 @@ static void fsl_usb2_mpc5121_exit(struct platform_device *pdev) pdata->regs = NULL; if (pdata->clk) { - clk_disable(pdata->clk); + clk_disable_unprepare(pdata->clk); clk_put(pdata->clk); } } -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 18/24] i2c: mpc: OF clock lookup for MPC512x
make the MPC I2C driver prepare and enable the peripheral clock ('per' for register access) in the MPC512x setup routine, make this clock setup non-fatal to allow for a migration period, remove the pre-enabling hack in the platform's clock driver Signed-off-by: Gerhard Sittig --- arch/powerpc/platforms/512x/clock-commonclk.c |1 - drivers/i2c/busses/i2c-mpc.c |9 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index b8963b7..49c52bc 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -692,7 +692,6 @@ static void mpc512x_clk_setup_clock_tree(int busfreq) /* some are not yet acquired by their respective drivers */ clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */ clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */ - clk_prepare_enable(clks[MPC512x_CLK_I2C]); /* * some have their individual clock subtree with separate clock * items and their individual enable counters, yet share a diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 7607dc0..13d6822 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -264,11 +265,19 @@ static void mpc_i2c_setup_512x(struct device_node *node, struct mpc_i2c *i2c, u32 clock, u32 prescaler) { + struct clk *clk; struct device_node *node_ctrl; void __iomem *ctrl; const u32 *pval; u32 idx; + /* enable clock for the I2C peripheral (non fatal) */ + clk = of_clk_get_by_name(node, "per"); + if (!IS_ERR(clk)) { + clk_prepare_enable(clk); + clk_put(clk); + } + /* Enable I2C interrupts for mpc5121 */ node_ctrl = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-i2c-ctrl"); -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 20/24] fs_enet: OF clock lookup (non-fatal), prepare and enable
device tree based clock lookup, must prepare clocks before enabling them, unprepare after disable, error check in the clock setup, remove the pre-enable workaround in the MPC512x platform's clock driver this change implements non-fatal clock lookup since not all platforms provide device tree specs for clocks, but failure to enable a specified clock is considered fatal Signed-off-by: Gerhard Sittig --- arch/powerpc/platforms/512x/clock-commonclk.c |1 - .../net/ethernet/freescale/fs_enet/fs_enet-main.c | 27 +++- include/linux/fs_enet_pd.h |3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index 49c52bc..e9451a7 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -691,7 +691,6 @@ static void mpc512x_clk_setup_clock_tree(int busfreq) clk_prepare_enable(clks[MPC512x_CLK_LPC]); /* boot media */ /* some are not yet acquired by their respective drivers */ clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */ - clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */ /* * some have their individual clock subtree with separate clock * items and their individual enable counters, yet share a diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index 8de53a1..df92e12 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -1020,6 +1020,21 @@ static int fs_enet_probe(struct platform_device *ofdev) fpi->cp_command = *data; } + /* make clock lookup non-fatal (the driver is shared among platforms), +* but require enable to succeed when a clock was specified/found +*/ + fpi->clk_per = clk_get(&ofdev->dev, "per"); + if (IS_ERR(fpi->clk_per)) + fpi->clk_per = NULL; + if (fpi->clk_per) { + int err; + err = clk_prepare_enable(fpi->clk_per); + if (err) { + ret = err; + goto out_clk_put; + } + } + fpi->rx_ring = 32; fpi->tx_ring = 32; fpi->rx_copybreak = 240; @@ -1028,7 +1043,7 @@ static int fs_enet_probe(struct platform_device *ofdev) fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link", NULL))) - goto out_free_fpi; + goto out_clk_dis; if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) { phy_connection_type = of_get_property(ofdev->dev.of_node, @@ -1108,6 +1123,12 @@ out_free_dev: free_netdev(ndev); out_put: of_node_put(fpi->phy_node); +out_clk_dis: + if (fpi->clk_per) + clk_disable_unprepare(fpi->clk_per); +out_clk_put: + if (fpi->clk_per) + clk_put(fpi->clk_per); out_free_fpi: kfree(fpi); return ret; @@ -1124,6 +1145,10 @@ static int fs_enet_remove(struct platform_device *ofdev) fep->ops->cleanup_data(ndev); dev_set_drvdata(fep->dev, NULL); of_node_put(fep->fpi->phy_node); + if (fep->fpi->clk_per) { + clk_disable_unprepare(fep->fpi->clk_per); + clk_put(fep->fpi->clk_per); + } free_netdev(ndev); return 0; } diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 51b7934..a978d0d 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h @@ -16,6 +16,7 @@ #ifndef FS_ENET_PD_H #define FS_ENET_PD_H +#include #include #include #include @@ -142,6 +143,8 @@ struct fs_platform_info { int use_rmii; /* use RMII mode */ int has_phy;/* if the network is phy container as well...*/ + + struct clk *clk_per;/* 'per' clock for register access */ }; struct fs_mii_fec_platform_info { u32 irq[32]; -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 21/24] [media] fsl-viu: OF clock lookup, prepare before enable
device tree based clock lookup, must prepare clocks before enabling them, unprepare after disable, error check in the clock setup Signed-off-by: Gerhard Sittig --- drivers/media/platform/fsl-viu.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 221ec42..b95aa43 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -1582,8 +1582,11 @@ static int viu_of_probe(struct platform_device *op) dev_err(&op->dev, "failed to find the clock module!\n"); ret = -ENODEV; goto err_clk; - } else { - clk_enable(viu_dev->clk); + } + ret = clk_prepare_enable(viu_dev->clk); + if (ret) { + dev_err(&op->dev, "failed to enable the clock!\n"); + goto err_clk_put; } /* reset VIU module */ @@ -1602,7 +1605,8 @@ static int viu_of_probe(struct platform_device *op) return ret; err_irq: - clk_disable(viu_dev->clk); + clk_disable_unprepare(viu_dev->clk); +err_clk_put: clk_put(viu_dev->clk); err_clk: video_unregister_device(viu_dev->vdev); @@ -1626,7 +1630,7 @@ static int viu_of_remove(struct platform_device *op) free_irq(dev->irq, (void *)dev); irq_dispose_mapping(dev->irq); - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); clk_put(dev->clk); video_unregister_device(dev->vdev); -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 23/24] clk: mpc512x: switch to COMMON_CLK, remove PPC_CLOCK
completely switch to, i.e. unconditionally use COMMON_CLK for the MPC512x platform, and retire the PPC_CLOCK implementation for that platform after the transition has completed Signed-off-by: Gerhard Sittig --- arch/powerpc/platforms/512x/Kconfig | 14 +- arch/powerpc/platforms/512x/Makefile |3 +- arch/powerpc/platforms/512x/clock.c | 753 -- 3 files changed, 2 insertions(+), 768 deletions(-) delete mode 100644 arch/powerpc/platforms/512x/clock.c diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index c5fcdd0..5aa3f4b 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -1,21 +1,9 @@ -config MPC512x_COMMON_CLK - bool "MPC512x platform uses COMMON_CLK" - default y - depends on PPC_MPC512x - help - This option is only here to support tests and comparison - during development and migration. This option will get - removed after the COMMON_CLK support for MPC512x has become - fully operational and all drivers were adjusted to explicitly - acquire their required clocks. - config PPC_MPC512x bool "512x-based boards" depends on 6xx + select COMMON_CLK select FSL_SOC select IPIC - select PPC_CLOCK if !MPC512x_COMMON_CLK - select COMMON_CLK if MPC512x_COMMON_CLK select PPC_PCI_CHOICE select FSL_PCI if PCI select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 1e05f9d..bb20116 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile @@ -1,8 +1,7 @@ # # Makefile for the Freescale PowerPC 512x linux kernel. # -obj-$(CONFIG_PPC_CLOCK)+= clock.o -obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o +obj-y += clock-commonclk.o obj-y += mpc512x_shared.o obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c deleted file mode 100644 index e504166..000 --- a/arch/powerpc/platforms/512x/clock.c +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved. - * - * Author: John Rigby - * - * Implements the clk api defined in include/linux/clk.h - * - *Original based on linux/arch/arm/mach-integrator/clock.c - * - *Copyright (C) 2004 ARM Limited. - *Written by Deep Blue Solutions Limited. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mpc512x.h" - -#undef CLK_DEBUG - -static int clocks_initialized; - -#define CLK_HAS_RATE 0x1 /* has rate in MHz */ -#define CLK_HAS_CTRL 0x2 /* has control reg and bit */ - -struct clk { - struct list_head node; - char name[32]; - int flags; - struct device *dev; - unsigned long rate; - struct module *owner; - void (*calc) (struct clk *); - struct clk *parent; - int reg, bit; /* CLK_HAS_CTRL */ - int div_shift; /* only used by generic_div_clk_calc */ -}; - -static LIST_HEAD(clocks); -static DEFINE_MUTEX(clocks_mutex); - -static struct clk *mpc5121_clk_get(struct device *dev, const char *id) -{ - struct clk *p, *clk = ERR_PTR(-ENOENT); - int dev_match; - int id_match; - - if (dev == NULL || id == NULL) - return clk; - - mutex_lock(&clocks_mutex); - list_for_each_entry(p, &clocks, node) { - dev_match = id_match = 0; - - if (dev == p->dev) - dev_match++; - if (strcmp(id, p->name) == 0) - id_match++; - if ((dev_match || id_match) && try_module_get(p->owner)) { - clk = p; - break; - } - } - mutex_unlock(&clocks_mutex); - - return clk; -} - -#ifdef CLK_DEBUG -static void dump_clocks(void) -{ - struct clk *p; - - mutex_lock(&clocks_mutex); - printk(KERN_INFO "CLOCKS:\n"); - list_for_each_entry(p, &clocks, node) { - pr_info(" %s=%ld", p->name, p->rate); - if (p->parent) - pr_cont(" %s=%ld", p->parent->name, - p->parent->rate); - if (p->flags & CLK_HAS_CTRL) - pr_cont(" reg/bit=%d/%d", p->reg, p->bit); - pr_cont("\n"); - } - mutex_unlock(&clocks_mutex); -} -#define
[PATCH v2 22/24] powerpc/fsl-pci: OF clock lookup, prepare before enable
device tree based clock lookup, must prepare clocks before enabling them, error check in the clock setup this change implements non-fatal clock lookup for compatibility with platforms that don't provide OF clock specs, but failure to enable a specified clock is considered fatal Signed-off-by: Gerhard Sittig --- arch/powerpc/sysdev/fsl_pci.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 46ac1dd..cb2ed92 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -17,6 +17,8 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ + +#include #include #include #include @@ -741,6 +743,7 @@ err0: int __init mpc83xx_add_bridge(struct device_node *dev) { + struct clk *clk; int ret; int len; struct pci_controller *hose; @@ -758,6 +761,18 @@ int __init mpc83xx_add_bridge(struct device_node *dev) } pr_debug("Adding PCI host bridge %s\n", dev->full_name); + /* non-fatal OF clock lookup, but fatal when a clock +* was specified yet could not get enabled */ + clk = of_clk_get_by_name(dev, "per"); + if (!IS_ERR(clk)) { + ret = clk_prepare_enable(clk); + clk_put(clk); + if (ret) { + pr_err("Could not enable peripheral clock\n"); + return ret; + } + } + /* Fetch host bridge registers address */ if (of_address_to_resource(dev, 0, &rsrc_reg)) { printk(KERN_WARNING "Can't get pci register base!\n"); -- 1.7.10.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 24/24] net: can: mscan: remove MPC512x non-COMMON_CLK code path
transition to the COMMON_CLK framework has completed for the MPC512x platform, remove the now obsolete code path of the mpc5xxx mscan driver which accessed clock control module registers directly Signed-off-by: Gerhard Sittig --- drivers/net/can/mscan/mpc5xxx_can.c | 136 --- 1 file changed, 136 deletions(-) diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index dd26ab6..cf5e4cfc 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -108,9 +108,6 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, #endif /* CONFIG_PPC_MPC52xx */ #ifdef CONFIG_PPC_MPC512x - -#if IS_ENABLED(CONFIG_COMMON_CLK) - static u32 mpc512x_can_get_clock(struct platform_device *ofdev, const char *clock_source, int *mscan_clksrc) { @@ -244,139 +241,6 @@ err_notavail: dev_err(&ofdev->dev, "cannot acquire or setup clock source\n"); return 0; } -#else /* COMMON_CLK */ -struct mpc512x_clockctl { - u32 spmr; /* System PLL Mode Reg */ - u32 sccr[2];/* System Clk Ctrl Reg 1 & 2 */ - u32 scfr1; /* System Clk Freq Reg 1 */ - u32 scfr2; /* System Clk Freq Reg 2 */ - u32 reserved; - u32 bcr;/* Bread Crumb Reg */ - u32 pccr[12]; /* PSC Clk Ctrl Reg 0-11 */ - u32 spccr; /* SPDIF Clk Ctrl Reg */ - u32 cccr; /* CFM Clk Ctrl Reg */ - u32 dccr; /* DIU Clk Cnfg Reg */ - u32 mccr[4];/* MSCAN Clk Ctrl Reg 1-3 */ -}; - -static struct of_device_id mpc512x_clock_ids[] = { - { .compatible = "fsl,mpc5121-clock", }, - {} -}; - -static u32 mpc512x_can_get_clock(struct platform_device *ofdev, -const char *clock_name, int *mscan_clksrc) -{ - struct mpc512x_clockctl __iomem *clockctl; - struct device_node *np_clock; - struct clk *sys_clk, *ref_clk; - int plen, clockidx, clocksrc = -1; - u32 sys_freq, val, clockdiv = 1, freq = 0; - const u32 *pval; - - np_clock = of_find_matching_node(NULL, mpc512x_clock_ids); - if (!np_clock) { - dev_err(&ofdev->dev, "couldn't find clock node\n"); - return 0; - } - clockctl = of_iomap(np_clock, 0); - if (!clockctl) { - dev_err(&ofdev->dev, "couldn't map clock registers\n"); - goto exit_put; - } - - /* Determine the MSCAN device index from the peripheral's -* physical address. Register address offsets against the -* IMMR base are: 0x1300, 0x1380, 0x2300, 0x2380 -*/ - pval = of_get_property(ofdev->dev.of_node, "reg", &plen); - BUG_ON(!pval || plen < sizeof(*pval)); - clockidx = (*pval & 0x80) ? 1 : 0; - if (*pval & 0x2000) - clockidx += 2; - - /* -* Clock source and divider selection: 3 different clock sources -* can be selected: "ip", "ref" or "sys". For the latter two, a -* clock divider can be defined as well. If the clock source is -* not specified by the device tree, we first try to find an -* optimal CAN source clock based on the system clock. If that -* is not posslible, the reference clock will be used. -*/ - if (clock_name && !strcmp(clock_name, "ip")) { - *mscan_clksrc = MSCAN_CLKSRC_IPS; - freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); - } else { - *mscan_clksrc = MSCAN_CLKSRC_BUS; - - pval = of_get_property(ofdev->dev.of_node, - "fsl,mscan-clock-divider", &plen); - if (pval && plen == sizeof(*pval)) - clockdiv = *pval; - if (!clockdiv) - clockdiv = 1; - - if (!clock_name || !strcmp(clock_name, "sys")) { - sys_clk = clk_get(&ofdev->dev, "sys_clk"); - if (IS_ERR(sys_clk)) { - dev_err(&ofdev->dev, "couldn't get sys_clk\n"); - goto exit_unmap; - } - /* Get and round up/down sys clock rate */ - sys_freq = 100 * - ((clk_get_rate(sys_clk) + 49) / 100); - - if (!clock_name) { - /* A multiple of 16 MHz would be optimal */ - if ((sys_freq % 1600) == 0) { - clocksrc = 0; - clockdiv = sys_freq / 1600; - freq = sys_freq / clockdiv; - } - } else { - clocksrc = 0; -
Re: [PATCH v2 18/24] i2c: mpc: OF clock lookup for MPC512x
On Thu, Jul 18, 2013 at 10:20:52PM +0200, Gerhard Sittig wrote: > + /* enable clock for the I2C peripheral (non fatal) */ > + clk = of_clk_get_by_name(node, "per"); > + if (!IS_ERR(clk)) { > + clk_prepare_enable(clk); > + clk_put(clk); > + } > + This kind of hacked up approach to the clk API is exactly the thing I really don't like seeing. I don't know what it is... is the clk API somehow difficult to use or what's the problem with doing stuff correctly? 1. Get the clock in your probe function. 2. Prepare it at the appropriate time. 3. Enable it appropriately. (or if you want to combine 2 and 3, use clk_prepare_enable().) 4. Ensure that enables/disables and prepares/unprepares are appropriately balanced. 5. 'put' the clock in your remove function. Certainly do not get-enable-put a clock. You're supposed to hold on to the clock all the time that you're actually using it. Final point - if you want to make it non-fatal, don't play games like: clk = clk_get(whatever); if (IS_ERR(clk)) clk = NULL; ... if (clk) clk_prepare(clk); Do this instead: clk = clk_get(whatever); ... if (!IS_ERR(clk)) clk_prepare(clk); etc. (And on this subject, I'm considering whether to make a change to the clk API where clk_prepare() and clk_enable() return zero when passed an error pointer - this means drivers with optional clocks don't have to burden themselves with these kinds of checks.) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 01/24] spi: mpc512x: cleanup clock API use
On Thu, Jul 18, 2013 at 07:00:32PM +0200, Gerhard Sittig wrote: > + psc_num = master->bus_num; > + snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); > + mps->clk_mclk = clk_get(dev, clk_name); > + if (IS_ERR(mps->clk_mclk)) > + goto free_irq; Should be using devm_clk_get(). signature.asc Description: Digital signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Inbound PCI and Memory Corruption
We are still stumped on this one, but during a review of the system setup one thing came up that we aren't sure about is the device tree and the DMA engine. It does seem that for incoming PCI transactions the Freescale DMA engine is not used. And in our device tree we have the DMA engine commented out. That is, the "fsl,mpc8349-dma" and "fsl,elo-dma" compatible items are not present in the FDT. I don't suppose this could be a problem? Thanks, Pete ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Inbound PCI and Memory Corruption
On Thu, 2013-07-18 at 14:30 -0700, Peter LaDow wrote: > We are still stumped on this one, but during a review of the system > setup one thing came up that we aren't sure about is the device tree > and the DMA engine. > > It does seem that for incoming PCI transactions the Freescale DMA > engine is not used. And in our device tree we have the DMA engine > commented out. That is, the "fsl,mpc8349-dma" and "fsl,elo-dma" > compatible items are not present in the FDT. > > I don't suppose this could be a problem? I doubt it but somebody from FSL might be able to give a better answer. I'm personally at a loss. It looks like you are doing everything right from what I can tell. That leaves us with some kind of oddball driver bug or a problem with the low level configuration of the PCIe bridge or the chip internal bus related to cache coherency maybe. Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH 4/4 V2] mmc: esdhc: Add broken timeout quirk for p4/p5 board
Thanks. Regards Haijun. > -Original Message- > From: Wood Scott-B07421 > Sent: Thursday, July 18, 2013 1:14 AM > To: Zhang Haijun-B42677 > Cc: linux-...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; > cbouatmai...@gmail.com; c...@laptop.org; Fleming Andy-AFLEMING; Zhang > Haijun-B42677; Zhang Haijun-B42677 > Subject: Re: [PATCH 4/4 V2] mmc: esdhc: Add broken timeout quirk for > p4/p5 board > > On 07/17/2013 05:11:31 AM, Haijun Zhang wrote: > > Sometimes command can't be completed within the time give in > > eSDHC_SYSCTL[DTOCV]. So just give the max value 0x14 to avoid this > > issue. > > > > Signed-off-by: Haijun Zhang > > --- > > changes for v2: > > - Rebuild patch of eSDHC host need long time to generate > > command interrupt > > > > drivers/mmc/host/sdhci-of-esdhc.c | 6 ++ > > 1 file changed, 6 insertions(+) > > > > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c > > b/drivers/mmc/host/sdhci-of-esdhc.c > > index 570bca8..30bfb5c 100644 > > --- a/drivers/mmc/host/sdhci-of-esdhc.c > > +++ b/drivers/mmc/host/sdhci-of-esdhc.c > > @@ -325,6 +325,12 @@ static void esdhc_of_platform_init(struct > > sdhci_host *host) > > > > if (vvn > VENDOR_V_22) > > host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; > > + > > + if ((SVR_SOC_VER(svr) == SVR_B4860) || > > + (SVR_SOC_VER(svr) == SVR_P5020) || > > + (SVR_SOC_VER(svr) == SVR_P5040) || > > + (SVR_SOC_VER(svr) == SVR_P4080)) > > + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; > > } > > Please don't line up the continuation lines of the if-condition with the > if-body. [Haijun Wrote:] I'll correct it. > > Please check variant SoCs as well. If the bug exists on p4080, then it > exists on p4040. Likewise with p5040/p5021, and p5020/p5010. > > Is it present on all revisions of these SoCs? How about p3041, which is > usually pretty similar to p5020? p2040/p2041? Is there an erratum > number for this problem? > [Haijun Wrote:] I only checked this on these boards. No errata number yet, This quirk only give the host max detecting time value to check card's response. No impact on performance or other functions. > -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH 2/4 V2] mmc: esdhc: workaround for dma err in the last system transaction
Hi, all Expect your advice and any comments. Thanks. Regards Haijun. > -Original Message- > From: Zhang Haijun-B42677 > Sent: Wednesday, July 17, 2013 6:11 PM > To: linux-...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org > Cc: cbouatmai...@gmail.com; c...@laptop.org; Wood Scott-B07421; Fleming > Andy-AFLEMING; Zhang Haijun-B42677; Zhang Haijun-B42677 > Subject: [PATCH 2/4 V2] mmc: esdhc: workaround for dma err in the last > system transaction > > A-004388: eSDHC DMA might not stop if error occurs on system transaction > > eSDHC DMA(SDMA/ADMA) might not stop if an error occurs in the last system > transaction. It may continue initiating additional transactions until > software reset for data/all is issued during error recovery. There is not > any data corruption to the SD data. The IRQSTAT[DMAE] is set when the > erratum occurs. > The only conditions under which issues occur are the following: > 1. SDMA - For SD Write , the error occurs in the last system transaction. > No issue for SD read > 2. ADMA > a. Block count is enabled: For SD write, the error occurs in the last > system transaction. There is no issue for SD read when block count is > enabled. > b. Block count is disabled: Block count is designated by the ADMA > descriptor table, and the error occurs in the last system transaction > when ADMA is executing last descriptor line of table. > > eSDHC may initiate additional system transactions. There is no data > integrity issue for case 1 and 2a described below. For case 2b, system > data might be corrupted. > > Workaround: Set eSDHC_SYSCTL[RSTD] when IRQSTAT[DMAE] is set. For cases > 2a and 2b above, add an extra descriptor line with zero data next to the > last descriptor line. > > Signed-off-by: Haijun Zhang > --- > changes for V2: > - Update the svr version list > > drivers/mmc/host/sdhci-of-esdhc.c | 112 > ++ > 1 file changed, 102 insertions(+), 10 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci- > of-esdhc.c > index 15039e2..adfaadd 100644 > --- a/drivers/mmc/host/sdhci-of-esdhc.c > +++ b/drivers/mmc/host/sdhci-of-esdhc.c > @@ -21,9 +21,13 @@ > #include > #include "sdhci-pltfm.h" > #include "sdhci-esdhc.h" > +#include > > #define VENDOR_V_22 0x12 > #define VENDOR_V_23 0x13 > + > +static u32 svr; > + > static u32 esdhc_readl(struct sdhci_host *host, int reg) { > u32 ret; > @@ -142,6 +146,26 @@ static void esdhc_writeb(struct sdhci_host *host, u8 > val, int reg) > sdhci_be32bs_writeb(host, val, reg); > } > > +static void esdhc_reset(struct sdhci_host *host, u8 mask) { > + u32 ier; > + u32 uninitialized_var(isav); > + > + if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) > + isav = esdhc_readl(host, SDHCI_INT_ENABLE); > + > + esdhc_writeb(host, mask, SDHCI_SOFTWARE_RESET); > + mdelay(100); > + > + if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) { > + ier = esdhc_readl(host, SDHCI_INT_ENABLE); > + ier &= ~SDHCI_INT_ALL_MASK; > + ier |= isav; > + esdhc_writel(host, ier, SDHCI_INT_ENABLE); > + esdhc_writel(host, ier, SDHCI_SIGNAL_ENABLE); > + } > +} > + > /* > * For Abort or Suspend after Stop at Block Gap, ignore the ADMA > * error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC]) @@ - > 156,25 +180,92 @@ static void esdhci_of_adma_workaround(struct sdhci_host > *host, u32 intmask) > dma_addr_t dmastart; > dma_addr_t dmanow; > > - tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); > + tmp = esdhc_readl(host, SDHCI_SLOT_INT_STATUS); > tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; > > applicable = (intmask & SDHCI_INT_DATA_END) && > (intmask & SDHCI_INT_BLK_GAP) && > (tmp == VENDOR_V_23); > - if (!applicable) > + if (applicable) { > + > + esdhc_reset(host, SDHCI_RESET_DATA); > + host->data->error = 0; > + dmastart = sg_dma_address(host->data->sg); > + dmanow = dmastart + host->data->bytes_xfered; > + > + /* Force update to the next DMA block boundary. */ > + dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + > + SDHCI_DEFAULT_BOUNDARY_SIZE; > + host->data->bytes_xfered = dmanow - dmastart; > + esdhc_writel(host, dmanow, SDHCI_DMA_ADDRESS); > + > return; > + } > > - host->data->error = 0; > - dmastart = sg_dma_address(host->data->sg); > - dmanow = dmastart + host->data->bytes_xfered; > /* > - * Force update to the next DMA block boundary. > + * Check for A-004388: eSDHC DMA might not stop if error > + * occurs on system transaction > + * Impact list: > + * T4240-R1.0 B4860-R1.0 P1010-R1.0 > + * P3041-R1.0-R2.0-R1.1 P2041-R1.0-R1.1-R2.0 > + * P5040-R2.0 >*/ > -
RE: [PATCH 1/4 V4] powerpc/85xx: Add support for 85xx cpu type detection
Hi, scott I had update this patch, this is the newest version. If there is no other problem, can you help merge this patch? I hope to make sure the following patch don't need to rebuild due to the change of this patch. Thanks. Regards Haijun. > -Original Message- > From: Zhang Haijun-B42677 > Sent: Wednesday, July 17, 2013 1:12 PM > To: linux-...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org > Cc: cbouatmai...@gmail.com; c...@laptop.org; Wood Scott-B07421; Fleming > Andy-AFLEMING; Zhang Haijun-B42677; Zhao Chenhui-B35336 > Subject: [PATCH 1/4 V4] powerpc/85xx: Add support for 85xx cpu type > detection > > Add this file to help detect cpu type in runtime. > These macros will be more favorable for driver to apply errata and > workaround to specified cpu type. > > Signed-off-by: Haijun Zhang > Signed-off-by: Zhao Chenhui > --- > changes for v4: > - Add new set of soc > > arch/powerpc/include/asm/mpc85xx.h | 92 > ++ > 1 file changed, 92 insertions(+) > create mode 100644 arch/powerpc/include/asm/mpc85xx.h > > diff --git a/arch/powerpc/include/asm/mpc85xx.h > b/arch/powerpc/include/asm/mpc85xx.h > new file mode 100644 > index 000..736d4ac > --- /dev/null > +++ b/arch/powerpc/include/asm/mpc85xx.h > @@ -0,0 +1,92 @@ > +/* > + * MPC85xx cpu type detection > + * > + * Copyright 2011-2012 Freescale Semiconductor, Inc. > + * > + * This is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#ifndef __ASM_PPC_MPC85XX_H > +#define __ASM_PPC_MPC85XX_H > + > +#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ > +#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ > +#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ > + > +/* Some parts define SVR[0:23] as the SOC version */ > +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version > fields */ > + > +#define SVR_8533 0x803400 > +#define SVR_8535 0x803701 > +#define SVR_8536 0x803700 > +#define SVR_8540 0x803000 > +#define SVR_8541 0x807200 > +#define SVR_8543 0x803200 > +#define SVR_8544 0x803401 > +#define SVR_8545 0x803102 > +#define SVR_8547 0x803101 > +#define SVR_8548 0x803100 > +#define SVR_8555 0x807100 > +#define SVR_8560 0x807000 > +#define SVR_8567 0x807501 > +#define SVR_8568 0x807500 > +#define SVR_8569 0x808000 > +#define SVR_8572 0x80E000 > +#define SVR_P10100x80F100 > +#define SVR_P10110x80E500 > +#define SVR_P10120x80E501 > +#define SVR_P10130x80E700 > +#define SVR_P10140x80F101 > +#define SVR_P10170x80F700 > +#define SVR_P10200x80E400 > +#define SVR_P10210x80E401 > +#define SVR_P10220x80E600 > +#define SVR_P10230x80F600 > +#define SVR_P10240x80E402 > +#define SVR_P10250x80E403 > +#define SVR_P20100x80E300 > +#define SVR_P20200x80E200 > +#define SVR_P20400x821000 > +#define SVR_P20410x821001 > +#define SVR_P30410x821103 > +#define SVR_P40400x820100 > +#define SVR_P40800x82 > +#define SVR_P50100x822100 > +#define SVR_P50200x822000 > +#define SVR_P50210X820500 > +#define SVR_P50400x820400 > +#define SVR_T42400x824000 > +#define SVR_T41200x824001 > +#define SVR_T41600x824100 > +#define SVR_C291 0x85 > +#define SVR_C292 0x850020 > +#define SVR_C293 0x850030 > +#define SVR_B48600X868000 > +#define SVR_G48600x868001 > +#define SVR_G40600x868003 > +#define SVR_B44400x868100 > +#define SVR_G44400x868101 > +#define SVR_B44200x868102 > +#define SVR_B42200x868103 > +#define SVR_T10400x852000 > +#define SVR_T10410x852001 > +#define SVR_T10420x852002 > +#define SVR_T10200x852100 > +#define SVR_T10210x852101 > +#define SVR_T10220x852102 > + > +#define SVR_8610 0x80A000 > +#define SVR_8641 0x809000 > +#define SVR_8641D0x809001 > + > +#define SVR_9130 0x860001 > +#define SVR_9131 0x86 > +#define SVR_9132 0x861000 > +#define SVR_9232 0x861400 > + > +#define SVR_Unknown 0xFF > + > +#endif > -- > 1.8.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/4 V3] mmc: esdhc: Correct host version of T4240-R1.0-R2.0
Vender version and sdhc spec version of T4240-R1.0-R2.0 is incorrect. The right value should be VVN=0x13, SVN = 0x1. The wrong version number will break down the ADMA data transfer. This defect only exist in T4240-R1.0-R2.0. Also share vvn and svr for public use. Signed-off-by: Haijun Zhang --- drivers/mmc/host/sdhci-of-esdhc.c | 31 ++- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index adfaadd..509e10d 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -26,7 +26,7 @@ #define VENDOR_V_220x12 #define VENDOR_V_230x13 -static u32 svr; +static u32 svr, vvn; static u32 esdhc_readl(struct sdhci_host *host, int reg) { @@ -43,11 +43,9 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the * the verdor version number, oxFE is SDHCI_HOST_VERSION. */ - if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) { - u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); - tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; - if (tmp > VENDOR_V_22) - ret |= SDHCI_CAN_DO_ADMA2; + if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1) && + (vvn > VENDOR_V_22)) { + ret |= SDHCI_CAN_DO_ADMA2; } return ret; @@ -63,6 +61,12 @@ static u16 esdhc_readw(struct sdhci_host *host, int reg) ret = in_be32(host->ioaddr + base) & 0x; else ret = (in_be32(host->ioaddr + base) >> shift) & 0x; + + /* T4240-R1.0-R2.0 had a incorrect vendor version and spec version */ + if ((reg == SDHCI_HOST_VERSION) && + ((SVR_SOC_VER(svr) == SVR_T4240) && (SVR_REV(svr) <= 0x20))) + ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200; + return ret; } @@ -175,17 +179,12 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask) */ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) { - u32 tmp; bool applicable; dma_addr_t dmastart; dma_addr_t dmanow; - tmp = esdhc_readl(host, SDHCI_SLOT_INT_STATUS); - tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; - applicable = (intmask & SDHCI_INT_DATA_END) && - (intmask & SDHCI_INT_BLK_GAP) && - (tmp == VENDOR_V_23); + (intmask & SDHCI_INT_BLK_GAP) && (vvn == VENDOR_V_23); if (applicable) { esdhc_reset(host, SDHCI_RESET_DATA); @@ -215,7 +214,7 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) ((SVR_SOC_VER(svr) == SVR_P1010) && (SVR_REV(svr) == 0x10)) || ((SVR_SOC_VER(svr) == SVR_P3041) && (SVR_REV(svr) <= 0x20)) || ((SVR_SOC_VER(svr) == SVR_P2041) && (SVR_REV(svr) <= 0x20)) || - ((SVR_SOC_VER(svr) == SVR_P5040) && SVR_REV(svr) == 0x20))) + ((SVR_SOC_VER(svr) == SVR_P5040) && (SVR_REV(svr) == 0x20 return; esdhc_reset(host, SDHCI_RESET_DATA); @@ -318,10 +317,9 @@ static void esdhc_of_resume(struct sdhci_host *host) static void esdhc_of_platform_init(struct sdhci_host *host) { - u32 vvn; + svr = mfspr(SPRN_SVR); + vvn = esdhc_readw(host, SDHCI_HOST_VERSION); - vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); - vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; if (vvn == VENDOR_V_22) host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; @@ -390,7 +388,6 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) struct device_node *np; int ret; - svr = mfspr(SPRN_SVR); host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0); if (IS_ERR(host)) return PTR_ERR(host); -- 1.8.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 00/10 v6] KVM: PPC: IOMMU in-kernel handling
On 07/16/2013 10:53 AM, Alexey Kardashevskiy wrote: > The changes are: > 1. rebased on v3.11-rc1 so the capability numbers changed again > 2. fixed multiple comments from maintainers > 3. "KVM: PPC: Add support for IOMMU in-kernel handling" is split into > 2 patches, the new one is "powerpc/iommu: rework to support realmode". > 4. IOMMU_API is now always enabled for KVM_BOOK3S_64. > > MOre details in the individual patch comments. > > Depends on "hashtable: add hash_for_each_possible_rcu_notrace()", > posted a while ago. > > > Alexey Kardashevskiy (10): > KVM: PPC: reserve a capability number for multitce support > KVM: PPC: reserve a capability and ioctl numbers for realmode VFIO Alex, could you please pull these 2 patches or tell what is wrong with them? Having them sooner in the kernel would let me ask for a headers update for QEMU and then I would try pushing miltiple TCE and VFIO support in QEMU. Thanks. -- Alexey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev