Merge tag 'imx-soc-3.12' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/soc
authorKevin Hilman <khilman@linaro.org>
Fri, 23 Aug 2013 18:38:51 +0000 (11:38 -0700)
committerKevin Hilman <khilman@linaro.org>
Fri, 23 Aug 2013 18:38:51 +0000 (11:38 -0700)
From Shawn Guo:

It contains a bunch of imx soc updates for 3.12.

- Add more ethernet phy fixups for imx6 boards
- Add some missing imx6q clocks into clock driver
- Add new clock types fixup mux and div to work around some ugly
  hardware defect
- Consolidate L2 cache initialization function, so that it can be used
  on more i.MX SoCs
- Replace magic numbers in mach-imx6q.c with well defined macros
- Small fixes for imx6q and pllv3 clock drivers
- Some random updates on imx defconfig files

* tag 'imx-soc-3.12' of git://git.linaro.org/people/shawnguo/linux-2.6: (33 commits)
  phy: micrel: Add definitions for common Micrel PHY registers
  ARM: imx: Re-select CONFIG_SND_SOC_IMX_MC13783 option
  ARM: imx: Move anatop related from board file to anatop driver
  ARM: imx_v6_v7_defconfig: Enable wireless support
  ARM: imx_v4_v5_defconfig: Cleanup imx_v4_v5_defconfig
  ARM: imx_v6_v7_defconfig: Add SATA support
  ARM: imx_v6_v7_defconfig: Cleanup imx_v6_v7_defconfig
  ARM: mx53: Allow suspend/resume
  ARM: mach-imx: Select ARM_CPU_SUSPEND at ARCH_MXC level
  ARM: imx_v6_v7_defconfig: Select CONFIG_TOUCHSCREEN_EGALAX
  ARM: imx6q: add vdoa gate clock
  ARM: imx6q: add the missing cko output selection
  ARM: imx6q: add cko2 clocks
  ARM: imx6q: add spdif gate clock
  ARM: imx: clk-pllv3: improve the timeout waiting method
  ARM: imx6: change some clocks to fixup clocks
  ARM: imx: add common clock support for fixup mux
  ARM: imx: add common clock support for fixup div
  ARM: imx: Select MIGHT_HAVE_CACHE_L2X0
  ARM: imx: fix imx_init_l2cache storage class
  ...

21 files changed:
Documentation/devicetree/bindings/clock/imx6q-clock.txt
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/mach-at91/board-dt-sama5.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/anatop.c
arch/arm/mach-imx/clk-fixup-div.c [new file with mode: 0644]
arch/arm/mach-imx/clk-fixup-mux.c [new file with mode: 0644]
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/clk-imx6sl.c
arch/arm/mach-imx/clk-pllv3.c
arch/arm/mach-imx/clk.c
arch/arm/mach-imx/clk.h
arch/arm/mach-imx/common.h
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-imx6sl.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/mach-imx/pm-imx5.c
arch/arm/mach-imx/system.c
include/linux/micrel_phy.h

index a0e104f0527e058843c1f01a33997ff64d8f37cb..5a90a724b52069c793b65c8d20899cc304818abd 100644 (file)
@@ -209,6 +209,12 @@ clocks and IDs.
        pll5_post_div           194
        pll5_video_div          195
        eim_slow                196
+       spdif                   197
+       cko2_sel                198
+       cko2_podf               199
+       cko2                    200
+       cko                     201
+       vdoa                    202
 
 Examples:
 
index f07a847b00c91d27504b059beb2090c13b618875..e958ebe7977984be0a2a30746b2acefcfadfecca 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -17,16 +16,18 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_MXC=y
 CONFIG_ARCH_MULTI_V4T=y
 CONFIG_ARCH_MULTI_V5=y
 # CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_MXC=y
+CONFIG_MXC_IRQ_PRIOR=y
 CONFIG_ARCH_MX1ADS=y
 CONFIG_MACH_SCB9328=y
 CONFIG_MACH_APF9328=y
 CONFIG_MACH_MX21ADS=y
 CONFIG_MACH_MX25_3DS=y
 CONFIG_MACH_EUKREA_CPUIMX25SD=y
+CONFIG_MACH_IMX25_DT=y
 CONFIG_MACH_MX27ADS=y
 CONFIG_MACH_PCM038=y
 CONFIG_MACH_CPUIMX27=y
@@ -39,8 +40,6 @@ CONFIG_MACH_PCA100=y
 CONFIG_MACH_MXT_TD60=y
 CONFIG_MACH_IMX27IPCAM=y
 CONFIG_MACH_IMX27_DT=y
-CONFIG_MXC_IRQ_PRIOR=y
-CONFIG_MXC_PWM=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -67,7 +66,6 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
@@ -123,24 +121,20 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_MEDIA_SUPPORT=y
-CONFIG_VIDEO_DEV=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_SOC_CAMERA=y
-CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_VIDEO_MX2=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_CODA=y
+CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_FB=y
 CONFIG_FB_IMX=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_PWM=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
 CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -157,7 +151,6 @@ CONFIG_USB_HID=m
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
-CONFIG_USB_ULPI=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
@@ -198,3 +191,5 @@ CONFIG_NLS_CODEPAGE_850=m
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_15=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
index 06686e7303a95d8e739fea7f635438e0bf91bc6a..5d488c24b13287303bebaa2ddbda22fe9b898f40 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_KERNEL_LZO=y
 CONFIG_SYSVIPC=y
@@ -17,10 +16,8 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_MXC=y
 CONFIG_ARCH_MULTI_V6=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_MACH_IMX31_DT=y
+CONFIG_ARCH_MXC=y
 CONFIG_MACH_MX31LILLY=y
 CONFIG_MACH_MX31LITE=y
 CONFIG_MACH_PCM037=y
@@ -30,6 +27,7 @@ CONFIG_MACH_MX31MOBOARD=y
 CONFIG_MACH_QONG=y
 CONFIG_MACH_ARMADILLO5X0=y
 CONFIG_MACH_KZM_ARM11_01=y
+CONFIG_MACH_IMX31_DT=y
 CONFIG_MACH_PCM043=y
 CONFIG_MACH_MX35_3DS=y
 CONFIG_MACH_VPR200=y
@@ -39,7 +37,6 @@ CONFIG_SOC_IMX53=y
 CONFIG_SOC_IMX6Q=y
 CONFIG_SOC_IMX6SL=y
 CONFIG_SOC_VF610=y
-CONFIG_MXC_PWM=y
 CONFIG_SMP=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT_VOLUNTARY=y
@@ -64,20 +61,24 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_LRO is not set
 CONFIG_IPV6=y
 CONFIG_NETFILTER=y
-# CONFIG_WIRELESS is not set
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
+CONFIG_IMX_WEIM=y
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_M25P80=y
 CONFIG_MTD_SST25L=y
@@ -88,6 +89,7 @@ CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_SRAM=y
 CONFIG_EEPROM_AT24=y
 CONFIG_EEPROM_AT25=y
 # CONFIG_SCSI_PROC_FS is not set
@@ -98,10 +100,11 @@ CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=y
 CONFIG_PATA_IMX=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
 CONFIG_CS89x0=y
 CONFIG_CS89x0_PLATFORM=y
 # CONFIG_NET_VENDOR_FARADAY is not set
@@ -115,7 +118,7 @@ CONFIG_SMC91X=y
 CONFIG_SMC911X=y
 CONFIG_SMSC911X=y
 # CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_WLAN is not set
+CONFIG_BRCMFMAC=m
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
@@ -124,6 +127,7 @@ CONFIG_KEYBOARD_IMX=y
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_EGALAX=y
 CONFIG_TOUCHSCREEN_MC13783=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MMA8450=y
@@ -133,13 +137,13 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_IMX=y
 CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_MXC_RNGA=y
-CONFIG_I2C=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_HELPER_AUTO is not set
-CONFIG_I2C_ALGOBIT=m
 CONFIG_I2C_ALGOPCF=m
 CONFIG_I2C_ALGOPCA=m
 CONFIG_I2C_IMX=y
@@ -155,30 +159,26 @@ CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_DA9052=y
 CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_DA9052=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_MEDIA_SUPPORT=y
-CONFIG_VIDEO_DEV=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_SOC_CAMERA=y
+CONFIG_VIDEO_MX3=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=y
 CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_DRM=y
-CONFIG_VIDEO_MX3=y
-CONFIG_FB=y
-CONFIG_LCD_PLATFORM=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
+CONFIG_LCD_PLATFORM=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
 CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -192,11 +192,12 @@ CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_USB_PHY=y
+CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_MXS_PHY=y
-CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
@@ -213,9 +214,10 @@ CONFIG_IMX_SDMA=y
 CONFIG_MXS_DMA=y
 CONFIG_STAGING=y
 CONFIG_DRM_IMX=y
-CONFIG_DRM_IMX_TVE=y
 CONFIG_DRM_IMX_FB_HELPER=y
 CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
+CONFIG_DRM_IMX_TVE=y
+CONFIG_DRM_IMX_LDB=y
 CONFIG_DRM_IMX_IPUV3_CORE=y
 CONFIG_DRM_IMX_IPUV3=y
 CONFIG_COMMON_CLK_DEBUG=y
@@ -269,3 +271,6 @@ CONFIG_CRC_CCITT=m
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
index ad95f6a23a2877b4aa917a0fecb8f72aeb4f9c00..bf00d15d954d3d3f1b6ce1d55ec5840890518fa4 100644 (file)
@@ -42,20 +42,15 @@ static int ksz9021rn_phy_fixup(struct phy_device *phy)
 {
        int value;
 
-#define GMII_RCCPSR    260
-#define GMII_RRDPSR    261
-#define GMII_ERCR      11
-#define GMII_ERDWR     12
-
        /* Set delay values */
-       value = GMII_RCCPSR | 0x8000;
-       phy_write(phy, GMII_ERCR, value);
+       value = MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW | 0x8000;
+       phy_write(phy, MICREL_KSZ9021_EXTREG_CTRL, value);
        value = 0xF2F4;
-       phy_write(phy, GMII_ERDWR, value);
-       value = GMII_RRDPSR | 0x8000;
-       phy_write(phy, GMII_ERCR, value);
+       phy_write(phy, MICREL_KSZ9021_EXTREG_DATA_WRITE, value);
+       value = MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW | 0x8000;
+       phy_write(phy, MICREL_KSZ9021_EXTREG_CTRL, value);
        value = 0x2222;
-       phy_write(phy, GMII_ERDWR, value);
+       phy_write(phy, MICREL_KSZ9021_EXTREG_DATA_WRITE, value);
 
        return 0;
 }
index f54656091a9d67dfe896e00ad909ad73d0674570..546723b305b6afac37eddd999df207396b8bd2f3 100644 (file)
@@ -1,6 +1,7 @@
 config ARCH_MXC
        bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
        select ARCH_REQUIRE_GPIOLIB
+       select ARM_CPU_SUSPEND if PM
        select ARM_PATCH_PHYS_VIRT
        select AUTO_ZRELADDR if !ZBOOT_ROM
        select CLKDEV_LOOKUP
@@ -8,6 +9,7 @@ config ARCH_MXC
        select GENERIC_ALLOCATOR
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
+       select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7
        select MULTI_IRQ_HANDLER
        select SPARSE_IRQ
        select USE_OF
@@ -785,7 +787,6 @@ config SOC_IMX6Q
        bool "i.MX6 Quad/DualLite support"
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
-       select ARM_CPU_SUSPEND if PM
        select ARM_ERRATA_754322
        select ARM_ERRATA_764369 if SMP
        select ARM_ERRATA_775420
index e20f22d58fd8f00618dd57732e5e9a17a25d88c3..5383c589ad719105d104c077bac14ff73e1933eb 100644 (file)
@@ -15,7 +15,8 @@ imx5-pm-$(CONFIG_PM) += pm-imx5.o
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y)
 
 obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
-                           clk-pfd.o clk-busy.o clk.o
+                           clk-pfd.o clk-busy.o clk.o \
+                           clk-fixup-div.o clk-fixup-mux.o
 
 obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
index 0cfa07dd9aa422aa6a5cb1b245dd3a07c4d4498d..ad3b755abb78a949d1b379757a11725a983f2d3b 100644 (file)
@@ -66,7 +66,7 @@ void imx_anatop_post_resume(void)
        imx_anatop_enable_weak2p5(false);
 }
 
-void imx_anatop_usb_chrg_detect_disable(void)
+static void imx_anatop_usb_chrg_detect_disable(void)
 {
        regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
                BM_ANADIG_USB_CHRG_DETECT_EN_B
@@ -100,4 +100,6 @@ void __init imx_anatop_init(void)
                pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
                return;
        }
+
+       imx_anatop_usb_chrg_detect_disable();
 }
diff --git a/arch/arm/mach-imx/clk-fixup-div.c b/arch/arm/mach-imx/clk-fixup-div.c
new file mode 100644 (file)
index 0000000..21db020
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw)
+#define div_mask(d)    ((1 << (d->width)) - 1)
+
+/**
+ * struct clk_fixup_div - imx integer fixup divider clock
+ * @divider: the parent class
+ * @ops: pointer to clk_ops of parent class
+ * @fixup: a hook to fixup the write value
+ *
+ * The imx fixup divider clock is a subclass of basic clk_divider
+ * with an addtional fixup hook.
+ */
+struct clk_fixup_div {
+       struct clk_divider divider;
+       const struct clk_ops *ops;
+       void (*fixup)(u32 *val);
+};
+
+static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw)
+{
+       struct clk_divider *divider = to_clk_div(hw);
+
+       return container_of(divider, struct clk_fixup_div, divider);
+}
+
+static unsigned long clk_fixup_div_recalc_rate(struct clk_hw *hw,
+                                        unsigned long parent_rate)
+{
+       struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
+
+       return fixup_div->ops->recalc_rate(&fixup_div->divider.hw, parent_rate);
+}
+
+static long clk_fixup_div_round_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long *prate)
+{
+       struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
+
+       return fixup_div->ops->round_rate(&fixup_div->divider.hw, rate, prate);
+}
+
+static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate,
+                           unsigned long parent_rate)
+{
+       struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw);
+       struct clk_divider *div = to_clk_div(hw);
+       unsigned int divider, value;
+       unsigned long flags = 0;
+       u32 val;
+
+       divider = parent_rate / rate;
+
+       /* Zero based divider */
+       value = divider - 1;
+
+       if (value > div_mask(div))
+               value = div_mask(div);
+
+       spin_lock_irqsave(div->lock, flags);
+
+       val = readl(div->reg);
+       val &= ~(div_mask(div) << div->shift);
+       val |= value << div->shift;
+       fixup_div->fixup(&val);
+       writel(val, div->reg);
+
+       spin_unlock_irqrestore(div->lock, flags);
+
+       return 0;
+}
+
+static const struct clk_ops clk_fixup_div_ops = {
+       .recalc_rate = clk_fixup_div_recalc_rate,
+       .round_rate = clk_fixup_div_round_rate,
+       .set_rate = clk_fixup_div_set_rate,
+};
+
+struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
+                                 void __iomem *reg, u8 shift, u8 width,
+                                 void (*fixup)(u32 *val))
+{
+       struct clk_fixup_div *fixup_div;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       if (!fixup)
+               return ERR_PTR(-EINVAL);
+
+       fixup_div = kzalloc(sizeof(*fixup_div), GFP_KERNEL);
+       if (!fixup_div)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &clk_fixup_div_ops;
+       init.flags = CLK_SET_RATE_PARENT;
+       init.parent_names = parent ? &parent : NULL;
+       init.num_parents = parent ? 1 : 0;
+
+       fixup_div->divider.reg = reg;
+       fixup_div->divider.shift = shift;
+       fixup_div->divider.width = width;
+       fixup_div->divider.lock = &imx_ccm_lock;
+       fixup_div->divider.hw.init = &init;
+       fixup_div->ops = &clk_divider_ops;
+       fixup_div->fixup = fixup;
+
+       clk = clk_register(NULL, &fixup_div->divider.hw);
+       if (IS_ERR(clk))
+               kfree(fixup_div);
+
+       return clk;
+}
diff --git a/arch/arm/mach-imx/clk-fixup-mux.c b/arch/arm/mach-imx/clk-fixup-mux.c
new file mode 100644 (file)
index 0000000..deb4b80
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "clk.h"
+
+#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
+
+/**
+ * struct clk_fixup_mux - imx integer fixup multiplexer clock
+ * @mux: the parent class
+ * @ops: pointer to clk_ops of parent class
+ * @fixup: a hook to fixup the write value
+ *
+ * The imx fixup multiplexer clock is a subclass of basic clk_mux
+ * with an addtional fixup hook.
+ */
+struct clk_fixup_mux {
+       struct clk_mux mux;
+       const struct clk_ops *ops;
+       void (*fixup)(u32 *val);
+};
+
+static inline struct clk_fixup_mux *to_clk_fixup_mux(struct clk_hw *hw)
+{
+       struct clk_mux *mux = to_clk_mux(hw);
+
+       return container_of(mux, struct clk_fixup_mux, mux);
+}
+
+static u8 clk_fixup_mux_get_parent(struct clk_hw *hw)
+{
+       struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw);
+
+       return fixup_mux->ops->get_parent(&fixup_mux->mux.hw);
+}
+
+static int clk_fixup_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw);
+       struct clk_mux *mux = to_clk_mux(hw);
+       unsigned long flags = 0;
+       u32 val;
+
+       spin_lock_irqsave(mux->lock, flags);
+
+       val = readl(mux->reg);
+       val &= ~(mux->mask << mux->shift);
+       val |= index << mux->shift;
+       fixup_mux->fixup(&val);
+       writel(val, mux->reg);
+
+       spin_unlock_irqrestore(mux->lock, flags);
+
+       return 0;
+}
+
+static const struct clk_ops clk_fixup_mux_ops = {
+       .get_parent = clk_fixup_mux_get_parent,
+       .set_parent = clk_fixup_mux_set_parent,
+};
+
+struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
+                             u8 shift, u8 width, const char **parents,
+                             int num_parents, void (*fixup)(u32 *val))
+{
+       struct clk_fixup_mux *fixup_mux;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       if (!fixup)
+               return ERR_PTR(-EINVAL);
+
+       fixup_mux = kzalloc(sizeof(*fixup_mux), GFP_KERNEL);
+       if (!fixup_mux)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &clk_fixup_mux_ops;
+       init.parent_names = parents;
+       init.num_parents = num_parents;
+
+       fixup_mux->mux.reg = reg;
+       fixup_mux->mux.shift = shift;
+       fixup_mux->mux.mask = BIT(width) - 1;
+       fixup_mux->mux.lock = &imx_ccm_lock;
+       fixup_mux->mux.hw.init = &init;
+       fixup_mux->ops = &clk_mux_ops;
+       fixup_mux->fixup = fixup;
+
+       clk = clk_register(NULL, &fixup_mux->mux.hw);
+       if (IS_ERR(clk))
+               kfree(fixup_mux);
+
+       return clk;
+}
index 86567d980b0743df9eadf44bfac489bc01634b9d..bbafa3ccacb567e075adcf9da3eed24f68b3e75a 100644 (file)
@@ -206,6 +206,17 @@ static const char *vpu_axi_sels[]  = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m",
 static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
                                    "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
                                    "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", };
+static const char *cko2_sels[] = {
+       "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1",
+       "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi",
+       "usdhc3", "dummy", "arm", "ipu1",
+       "ipu2", "vdo_axi", "osc", "gpu2d_core",
+       "gpu3d_core", "usdhc2", "ssi1", "ssi2",
+       "ssi3", "gpu3d_shader", "vpu_axi", "can_root",
+       "ldb_di0", "ldb_di1", "esai", "eim_slow",
+       "uart_serial", "spdif", "asrc", "hsi_tx",
+};
+static const char *cko_sels[] = { "cko1", "cko2", };
 
 enum mx6q_clks {
        dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
@@ -239,7 +250,8 @@ enum mx6q_clks {
        pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
        ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
        sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
-       usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow, clk_max
+       usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
+       spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -384,19 +396,21 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[ipu2_di1_sel]     = imx_clk_mux("ipu2_di1_sel",     base + 0x38, 9,  3, ipu2_di1_sels,     ARRAY_SIZE(ipu2_di1_sels));
        clk[hsi_tx_sel]       = imx_clk_mux("hsi_tx_sel",       base + 0x30, 28, 1, hsi_tx_sels,       ARRAY_SIZE(hsi_tx_sels));
        clk[pcie_axi_sel]     = imx_clk_mux("pcie_axi_sel",     base + 0x18, 10, 1, pcie_axi_sels,     ARRAY_SIZE(pcie_axi_sels));
-       clk[ssi1_sel]         = imx_clk_mux("ssi1_sel",         base + 0x1c, 10, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
-       clk[ssi2_sel]         = imx_clk_mux("ssi2_sel",         base + 0x1c, 12, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
-       clk[ssi3_sel]         = imx_clk_mux("ssi3_sel",         base + 0x1c, 14, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
-       clk[usdhc1_sel]       = imx_clk_mux("usdhc1_sel",       base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-       clk[usdhc2_sel]       = imx_clk_mux("usdhc2_sel",       base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-       clk[usdhc3_sel]       = imx_clk_mux("usdhc3_sel",       base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-       clk[usdhc4_sel]       = imx_clk_mux("usdhc4_sel",       base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+       clk[ssi1_sel]         = imx_clk_fixup_mux("ssi1_sel",   base + 0x1c, 10, 2, ssi_sels,          ARRAY_SIZE(ssi_sels),          imx_cscmr1_fixup);
+       clk[ssi2_sel]         = imx_clk_fixup_mux("ssi2_sel",   base + 0x1c, 12, 2, ssi_sels,          ARRAY_SIZE(ssi_sels),          imx_cscmr1_fixup);
+       clk[ssi3_sel]         = imx_clk_fixup_mux("ssi3_sel",   base + 0x1c, 14, 2, ssi_sels,          ARRAY_SIZE(ssi_sels),          imx_cscmr1_fixup);
+       clk[usdhc1_sel]       = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),        imx_cscmr1_fixup);
+       clk[usdhc2_sel]       = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),        imx_cscmr1_fixup);
+       clk[usdhc3_sel]       = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),        imx_cscmr1_fixup);
+       clk[usdhc4_sel]       = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),        imx_cscmr1_fixup);
        clk[enfc_sel]         = imx_clk_mux("enfc_sel",         base + 0x2c, 16, 2, enfc_sels,         ARRAY_SIZE(enfc_sels));
-       clk[emi_sel]          = imx_clk_mux("emi_sel",          base + 0x1c, 27, 2, emi_sels,          ARRAY_SIZE(emi_sels));
-       clk[emi_slow_sel]     = imx_clk_mux("emi_slow_sel",     base + 0x1c, 29, 2, emi_slow_sels,     ARRAY_SIZE(emi_slow_sels));
+       clk[emi_sel]          = imx_clk_fixup_mux("emi_sel",      base + 0x1c, 27, 2, emi_sels,        ARRAY_SIZE(emi_sels),          imx_cscmr1_fixup);
+       clk[emi_slow_sel]     = imx_clk_fixup_mux("emi_slow_sel", base + 0x1c, 29, 2, emi_slow_sels,   ARRAY_SIZE(emi_slow_sels),     imx_cscmr1_fixup);
        clk[vdo_axi_sel]      = imx_clk_mux("vdo_axi_sel",      base + 0x18, 11, 1, vdo_axi_sels,      ARRAY_SIZE(vdo_axi_sels));
        clk[vpu_axi_sel]      = imx_clk_mux("vpu_axi_sel",      base + 0x18, 14, 2, vpu_axi_sels,      ARRAY_SIZE(vpu_axi_sels));
        clk[cko1_sel]         = imx_clk_mux("cko1_sel",         base + 0x60, 0,  4, cko1_sels,         ARRAY_SIZE(cko1_sels));
+       clk[cko2_sel]         = imx_clk_mux("cko2_sel",         base + 0x60, 16, 5, cko2_sels,         ARRAY_SIZE(cko2_sels));
+       clk[cko]              = imx_clk_mux("cko",              base + 0x60, 8, 1,  cko_sels,          ARRAY_SIZE(cko_sels));
 
        /*                              name         reg      shift width busy: reg, shift parent_names  num_parents */
        clk[periph]  = imx_clk_busy_mux("periph",  base + 0x14, 25,  1,   base + 0x48, 5,  periph_sels,  ARRAY_SIZE(periph_sels));
@@ -406,7 +420,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[periph_clk2]      = imx_clk_divider("periph_clk2",      "periph_clk2_sel",   base + 0x14, 27, 3);
        clk[periph2_clk2]     = imx_clk_divider("periph2_clk2",     "periph2_clk2_sel",  base + 0x14, 0,  3);
        clk[ipg]              = imx_clk_divider("ipg",              "ahb",               base + 0x14, 8,  2);
-       clk[ipg_per]          = imx_clk_divider("ipg_per",          "ipg",               base + 0x1c, 0,  6);
+       clk[ipg_per]          = imx_clk_fixup_divider("ipg_per",    "ipg",               base + 0x1c, 0,  6, imx_cscmr1_fixup);
        clk[esai_pred]        = imx_clk_divider("esai_pred",        "esai_sel",          base + 0x28, 9,  3);
        clk[esai_podf]        = imx_clk_divider("esai_podf",        "esai_pred",         base + 0x28, 25, 3);
        clk[asrc_pred]        = imx_clk_divider("asrc_pred",        "asrc_sel",          base + 0x30, 12, 3);
@@ -442,10 +456,11 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[usdhc4_podf]      = imx_clk_divider("usdhc4_podf",      "usdhc4_sel",        base + 0x24, 22, 3);
        clk[enfc_pred]        = imx_clk_divider("enfc_pred",        "enfc_sel",          base + 0x2c, 18, 3);
        clk[enfc_podf]        = imx_clk_divider("enfc_podf",        "enfc_pred",         base + 0x2c, 21, 6);
-       clk[emi_podf]         = imx_clk_divider("emi_podf",         "emi_sel",           base + 0x1c, 20, 3);
-       clk[emi_slow_podf]    = imx_clk_divider("emi_slow_podf",    "emi_slow_sel",      base + 0x1c, 23, 3);
+       clk[emi_podf]         = imx_clk_fixup_divider("emi_podf",   "emi_sel",           base + 0x1c, 20, 3, imx_cscmr1_fixup);
+       clk[emi_slow_podf]    = imx_clk_fixup_divider("emi_slow_podf", "emi_slow_sel",   base + 0x1c, 23, 3, imx_cscmr1_fixup);
        clk[vpu_axi_podf]     = imx_clk_divider("vpu_axi_podf",     "vpu_axi_sel",       base + 0x24, 25, 3);
        clk[cko1_podf]        = imx_clk_divider("cko1_podf",        "cko1_sel",          base + 0x60, 4,  3);
+       clk[cko2_podf]        = imx_clk_divider("cko2_podf",        "cko2_sel",          base + 0x60, 21, 3);
 
        /*                                            name                 parent_name    reg        shift width busy: reg, shift */
        clk[axi]               = imx_clk_busy_divider("axi",               "axi_sel",     base + 0x14, 16,  3,   base + 0x48, 0);
@@ -486,6 +501,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[i2c3]         = imx_clk_gate2("i2c3",          "ipg_per",           base + 0x70, 10);
        clk[iim]          = imx_clk_gate2("iim",           "ipg",               base + 0x70, 12);
        clk[enfc]         = imx_clk_gate2("enfc",          "enfc_podf",         base + 0x70, 14);
+       clk[vdoa]         = imx_clk_gate2("vdoa",          "vdo_axi",           base + 0x70, 26);
        clk[ipu1]         = imx_clk_gate2("ipu1",          "ipu1_podf",         base + 0x74, 0);
        clk[ipu1_di0]     = imx_clk_gate2("ipu1_di0",      "ipu1_di0_sel",      base + 0x74, 2);
        clk[ipu1_di1]     = imx_clk_gate2("ipu1_di1",      "ipu1_di1_sel",      base + 0x74, 4);
@@ -521,6 +537,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[sata]         = imx_clk_gate2("sata",          "ipg",               base + 0x7c, 4);
        clk[sdma]         = imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
        clk[spba]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
+       clk[spdif]        = imx_clk_gate2("spdif",         "spdif_podf",        base + 0x7c, 14);
        clk[ssi1_ipg]     = imx_clk_gate2("ssi1_ipg",      "ipg",               base + 0x7c, 18);
        clk[ssi2_ipg]     = imx_clk_gate2("ssi2_ipg",      "ipg",               base + 0x7c, 20);
        clk[ssi3_ipg]     = imx_clk_gate2("ssi3_ipg",      "ipg",               base + 0x7c, 22);
@@ -535,6 +552,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[vdo_axi]      = imx_clk_gate2("vdo_axi",       "vdo_axi_sel",       base + 0x80, 12);
        clk[vpu_axi]      = imx_clk_gate2("vpu_axi",       "vpu_axi_podf",      base + 0x80, 14);
        clk[cko1]         = imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
+       clk[cko2]         = imx_clk_gate("cko2",           "cko2_podf",         base + 0x60, 24);
 
        for (i = 0; i < ARRAY_SIZE(clk); i++)
                if (IS_ERR(clk[i]))
@@ -554,7 +572,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
        clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
 
-       if (imx6q_revision() != IMX_CHIP_REVISION_1_0) {
+       if ((imx6q_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) {
                clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
                clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
        }
index a307ac22dffe6244276538e84c33f282b4a2a25c..a5c3c5d21aeedbcb324bca659730948f3e8d1a36 100644 (file)
@@ -138,14 +138,14 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        clks[IMX6SL_CLK_PERIPH_CLK2_SEL]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 2, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
        clks[IMX6SL_CLK_CSI_SEL]          = imx_clk_mux("csi_sel",          base + 0x3c, 9,  2, csi_lcdif_sels,    ARRAY_SIZE(csi_lcdif_sels));
        clks[IMX6SL_CLK_LCDIF_AXI_SEL]    = imx_clk_mux("lcdif_axi_sel",    base + 0x3c, 14, 2, csi_lcdif_sels,    ARRAY_SIZE(csi_lcdif_sels));
-       clks[IMX6SL_CLK_USDHC1_SEL]       = imx_clk_mux("usdhc1_sel",       base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-       clks[IMX6SL_CLK_USDHC2_SEL]       = imx_clk_mux("usdhc2_sel",       base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-       clks[IMX6SL_CLK_USDHC3_SEL]       = imx_clk_mux("usdhc3_sel",       base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-       clks[IMX6SL_CLK_USDHC4_SEL]       = imx_clk_mux("usdhc4_sel",       base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-       clks[IMX6SL_CLK_SSI1_SEL]         = imx_clk_mux("ssi1_sel",         base + 0x1c, 10, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
-       clks[IMX6SL_CLK_SSI2_SEL]         = imx_clk_mux("ssi2_sel",         base + 0x1c, 12, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
-       clks[IMX6SL_CLK_SSI3_SEL]         = imx_clk_mux("ssi3_sel",         base + 0x1c, 14, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
-       clks[IMX6SL_CLK_PERCLK_SEL]       = imx_clk_mux("perclk_sel",       base + 0x1c, 6,  1, perclk_sels,       ARRAY_SIZE(perclk_sels));
+       clks[IMX6SL_CLK_USDHC1_SEL]       = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),  imx_cscmr1_fixup);
+       clks[IMX6SL_CLK_USDHC2_SEL]       = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),  imx_cscmr1_fixup);
+       clks[IMX6SL_CLK_USDHC3_SEL]       = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),  imx_cscmr1_fixup);
+       clks[IMX6SL_CLK_USDHC4_SEL]       = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels),  imx_cscmr1_fixup);
+       clks[IMX6SL_CLK_SSI1_SEL]         = imx_clk_fixup_mux("ssi1_sel",   base + 0x1c, 10, 2, ssi_sels,          ARRAY_SIZE(ssi_sels),    imx_cscmr1_fixup);
+       clks[IMX6SL_CLK_SSI2_SEL]         = imx_clk_fixup_mux("ssi2_sel",   base + 0x1c, 12, 2, ssi_sels,          ARRAY_SIZE(ssi_sels),    imx_cscmr1_fixup);
+       clks[IMX6SL_CLK_SSI3_SEL]         = imx_clk_fixup_mux("ssi3_sel",   base + 0x1c, 14, 2, ssi_sels,          ARRAY_SIZE(ssi_sels),    imx_cscmr1_fixup);
+       clks[IMX6SL_CLK_PERCLK_SEL]       = imx_clk_fixup_mux("perclk_sel", base + 0x1c, 6,  1, perclk_sels,       ARRAY_SIZE(perclk_sels), imx_cscmr1_fixup);
        clks[IMX6SL_CLK_PXP_AXI_SEL]      = imx_clk_mux("pxp_axi_sel",      base + 0x34, 6,  3, epdc_pxp_sels,     ARRAY_SIZE(epdc_pxp_sels));
        clks[IMX6SL_CLK_EPDC_AXI_SEL]     = imx_clk_mux("epdc_axi_sel",     base + 0x34, 15, 3, epdc_pxp_sels,     ARRAY_SIZE(epdc_pxp_sels));
        clks[IMX6SL_CLK_GPU2D_OVG_SEL]    = imx_clk_mux("gpu2d_ovg_sel",    base + 0x18, 4,  2, gpu2d_ovg_sels,    ARRAY_SIZE(gpu2d_ovg_sels));
@@ -179,14 +179,14 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        clks[IMX6SL_CLK_SSI2_PODF]         = imx_clk_divider("ssi2_podf",         "ssi2_pred",         base + 0x2c, 0,  6);
        clks[IMX6SL_CLK_SSI3_PRED]         = imx_clk_divider("ssi3_pred",         "ssi3_sel",          base + 0x28, 22, 3);
        clks[IMX6SL_CLK_SSI3_PODF]         = imx_clk_divider("ssi3_podf",         "ssi3_pred",         base + 0x28, 16, 6);
-       clks[IMX6SL_CLK_PERCLK]            = imx_clk_divider("perclk",            "perclk_sel",        base + 0x1c, 0,  6);
+       clks[IMX6SL_CLK_PERCLK]            = imx_clk_fixup_divider("perclk",      "perclk_sel",        base + 0x1c, 0,  6, imx_cscmr1_fixup);
        clks[IMX6SL_CLK_PXP_AXI_PODF]      = imx_clk_divider("pxp_axi_podf",      "pxp_axi_sel",       base + 0x34, 3,  3);
        clks[IMX6SL_CLK_EPDC_AXI_PODF]     = imx_clk_divider("epdc_axi_podf",     "epdc_axi_sel",      base + 0x34, 12, 3);
        clks[IMX6SL_CLK_GPU2D_OVG_PODF]    = imx_clk_divider("gpu2d_ovg_podf",    "gpu2d_ovg_sel",     base + 0x18, 26, 3);
        clks[IMX6SL_CLK_GPU2D_PODF]        = imx_clk_divider("gpu2d_podf",        "gpu2d_sel",         base + 0x18, 29, 3);
        clks[IMX6SL_CLK_LCDIF_PIX_PRED]    = imx_clk_divider("lcdif_pix_pred",    "lcdif_pix_sel",     base + 0x38, 3,  3);
        clks[IMX6SL_CLK_EPDC_PIX_PRED]     = imx_clk_divider("epdc_pix_pred",     "epdc_pix_sel",      base + 0x38, 12, 3);
-       clks[IMX6SL_CLK_LCDIF_PIX_PODF]    = imx_clk_divider("lcdif_pix_podf",    "lcdif_pix_pred",    base + 0x1c, 20, 3);
+       clks[IMX6SL_CLK_LCDIF_PIX_PODF]    = imx_clk_fixup_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3, imx_cscmr1_fixup);
        clks[IMX6SL_CLK_EPDC_PIX_PODF]     = imx_clk_divider("epdc_pix_podf",     "epdc_pix_pred",     base + 0x18, 23, 3);
        clks[IMX6SL_CLK_SPDIF0_PRED]       = imx_clk_divider("spdif0_pred",       "spdif0_sel",        base + 0x30, 25, 3);
        clks[IMX6SL_CLK_SPDIF0_PODF]       = imx_clk_divider("spdif0_podf",       "spdif0_pred",       base + 0x30, 22, 3);
index a9fad5f8d340b50fb50e2348a6e761623be50911..f6640b6a7b3128a7ca6a6d8d31578419ea1be431 100644 (file)
@@ -48,7 +48,7 @@ struct clk_pllv3 {
 static int clk_pllv3_prepare(struct clk_hw *hw)
 {
        struct clk_pllv3 *pll = to_clk_pllv3(hw);
-       unsigned long timeout = jiffies + msecs_to_jiffies(10);
+       unsigned long timeout;
        u32 val;
 
        val = readl_relaxed(pll->base);
@@ -59,12 +59,19 @@ static int clk_pllv3_prepare(struct clk_hw *hw)
                val &= ~BM_PLL_POWER;
        writel_relaxed(val, pll->base);
 
+       timeout = jiffies + msecs_to_jiffies(10);
        /* Wait for PLL to lock */
-       while (!(readl_relaxed(pll->base) & BM_PLL_LOCK))
+       do {
+               if (readl_relaxed(pll->base) & BM_PLL_LOCK)
+                       break;
                if (time_after(jiffies, timeout))
-                       return -ETIMEDOUT;
+                       break;
+       } while (1);
 
-       return 0;
+       if (readl_relaxed(pll->base) & BM_PLL_LOCK)
+               return 0;
+       else
+               return -ETIMEDOUT;
 }
 
 static void clk_pllv3_unprepare(struct clk_hw *hw)
index 55bc80a00666412b8d7c53daaba26dced5e2eb95..edc35df7bed4a0da6d72dde245ca9257fc296805 100644 (file)
@@ -37,3 +37,29 @@ struct clk * __init imx_obtain_fixed_clock(
                clk = imx_clk_fixed(name, rate);
        return clk;
 }
+
+/*
+ * This fixups the register CCM_CSCMR1 write value.
+ * The write/read/divider values of the aclk_podf field
+ * of that register have the relationship described by
+ * the following table:
+ *
+ * write value       read value        divider
+ * 3b'000            3b'110            7
+ * 3b'001            3b'111            8
+ * 3b'010            3b'100            5
+ * 3b'011            3b'101            6
+ * 3b'100            3b'010            3
+ * 3b'101            3b'011            4
+ * 3b'110            3b'000            1
+ * 3b'111            3b'001            2(default)
+ *
+ * That's why we do the xor operation below.
+ */
+#define CSCMR1_FIXUP   0x00600000
+
+void imx_cscmr1_fixup(u32 *val)
+{
+       *val ^= CSCMR1_FIXUP;
+       return;
+}
index 0e4e8bb261b945c1fb22d32b9e693592f17dfa41..3451f1f8ba1ffbbde02f11984158ae09b8d4e1c6 100644 (file)
@@ -6,6 +6,8 @@
 
 extern spinlock_t imx_ccm_lock;
 
+extern void imx_cscmr1_fixup(u32 *val);
+
 struct clk *imx_clk_pllv1(const char *name, const char *parent,
                void __iomem *base);
 
@@ -49,6 +51,14 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
                             u8 width, void __iomem *busy_reg, u8 busy_shift,
                             const char **parent_names, int num_parents);
 
+struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
+                                 void __iomem *reg, u8 shift, u8 width,
+                                 void (*fixup)(u32 *val));
+
+struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
+                             u8 shift, u8 width, const char **parents,
+                             int num_parents, void (*fixup)(u32 *val));
+
 static inline struct clk *imx_clk_fixed(const char *name, int rate)
 {
        return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
index cb6c838b63edad7841ade9fcad0eb5ec82ebc51a..4517fd760bfc6d0c55a160f7fa22f8f3e1ae778c 100644 (file)
@@ -137,7 +137,6 @@ extern void imx_gpc_restore_all(void);
 extern void imx_anatop_init(void);
 extern void imx_anatop_pre_suspend(void);
 extern void imx_anatop_post_resume(void);
-extern void imx_anatop_usb_chrg_detect_disable(void);
 extern u32 imx_anatop_get_digprog(void);
 extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
 extern void imx6q_set_chicken_bit(void);
@@ -147,12 +146,10 @@ extern int imx_cpu_kill(unsigned int cpu);
 
 #ifdef CONFIG_PM
 extern void imx6q_pm_init(void);
-extern void imx51_pm_init(void);
-extern void imx53_pm_init(void);
+extern void imx5_pm_init(void);
 #else
 static inline void imx6q_pm_init(void) {}
-static inline void imx51_pm_init(void) {}
-static inline void imx53_pm_init(void) {}
+static inline void imx5_pm_init(void) {}
 #endif
 
 #ifdef CONFIG_NEON
@@ -161,6 +158,12 @@ extern int mx51_neon_fixup(void);
 static inline int mx51_neon_fixup(void) { return 0; }
 #endif
 
+#ifdef CONFIG_CACHE_L2X0
+extern void imx_init_l2cache(void);
+#else
+static inline void imx_init_l2cache(void) {}
+#endif
+
 extern struct smp_operations imx_smp_ops;
 
 #endif
index 7be13f8e69a01f22b43d28b4b22a42a23f006c8d..1e093abe7b956ff2abffa9fb2f1caa6ce1ad4785 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/regmap.h>
 #include <linux/micrel_phy.h>
 #include <linux/mfd/syscon.h>
-#include <asm/hardware/cache-l2x0.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
@@ -103,18 +103,65 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 {
        if (IS_BUILTIN(CONFIG_PHYLIB)) {
                /* min rx data delay */
-               phy_write(phydev, 0x0b, 0x8105);
-               phy_write(phydev, 0x0c, 0x0000);
+               phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+                       0x8000 | MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW);
+               phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0x0000);
 
                /* max rx/tx clock delay, min rx/tx control delay */
-               phy_write(phydev, 0x0b, 0x8104);
-               phy_write(phydev, 0x0c, 0xf0f0);
-               phy_write(phydev, 0x0b, 0x104);
+               phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+                       0x8000 | MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW);
+               phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0xf0f0);
+               phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+                       MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW);
        }
 
        return 0;
 }
 
+static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
+{
+       phy_write(dev, 0x0d, device);
+       phy_write(dev, 0x0e, reg);
+       phy_write(dev, 0x0d, (1 << 14) | device);
+       phy_write(dev, 0x0e, val);
+}
+
+static int ksz9031rn_phy_fixup(struct phy_device *dev)
+{
+       /*
+        * min rx data delay, max rx/tx clock delay,
+        * min rx/tx control delay
+        */
+       mmd_write_reg(dev, 2, 4, 0);
+       mmd_write_reg(dev, 2, 5, 0);
+       mmd_write_reg(dev, 2, 8, 0x003ff);
+
+       return 0;
+}
+
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+       u16 val;
+
+       /* To enable AR8031 output a 125MHz clk from CLK_25M */
+       phy_write(dev, 0xd, 0x7);
+       phy_write(dev, 0xe, 0x8016);
+       phy_write(dev, 0xd, 0x4007);
+
+       val = phy_read(dev, 0xe);
+       val &= 0xffe3;
+       val |= 0x18;
+       phy_write(dev, 0xe, val);
+
+       /* introduce tx clock delay */
+       phy_write(dev, 0x1d, 0x5);
+       val = phy_read(dev, 0x1e);
+       val |= 0x0100;
+       phy_write(dev, 0x1e, val);
+
+       return 0;
+}
+
 static void __init imx6q_sabrelite_cko1_setup(void)
 {
        struct clk *cko1_sel, *ahb, *cko1;
@@ -139,12 +186,18 @@ put_clk:
                clk_put(cko1);
 }
 
-static void __init imx6q_sabrelite_init(void)
+#define PHY_ID_AR8031  0x004dd074
+
+static void __init imx6q_enet_phy_init(void)
 {
-       if (IS_BUILTIN(CONFIG_PHYLIB))
+       if (IS_BUILTIN(CONFIG_PHYLIB)) {
                phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
                                ksz9021rn_phy_fixup);
-       imx6q_sabrelite_cko1_setup();
+               phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
+                               ksz9031rn_phy_fixup);
+               phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+                               ar8031_phy_fixup);
+       }
 }
 
 static void __init imx6q_sabresd_cko1_setup(void)
@@ -192,29 +245,28 @@ static void __init imx6q_1588_init(void)
 
        gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
        if (!IS_ERR(gpr))
-               regmap_update_bits(gpr, 0x4, 1 << 21, 1 << 21);
+               regmap_update_bits(gpr, IOMUXC_GPR1,
+                               IMX6Q_GPR1_ENET_CLK_SEL_MASK,
+                               IMX6Q_GPR1_ENET_CLK_SEL_ANATOP);
        else
                pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
 
 }
-static void __init imx6q_usb_init(void)
-{
-       imx_anatop_usb_chrg_detect_disable();
-}
 
 static void __init imx6q_init_machine(void)
 {
        if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
-               imx6q_sabrelite_init();
+               imx6q_sabrelite_cko1_setup();
        else if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
                        of_machine_is_compatible("fsl,imx6dl-sabresd"))
                imx6q_sabresd_init();
 
+       imx6q_enet_phy_init();
+
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
        imx_anatop_init();
        imx6q_pm_init();
-       imx6q_usb_init();
        imx6q_1588_init();
 }
 
@@ -297,44 +349,10 @@ static void __init imx6q_map_io(void)
        imx_scu_map_io();
 }
 
-#ifdef CONFIG_CACHE_L2X0
-static void __init imx6q_init_l2cache(void)
-{
-       void __iomem *l2x0_base;
-       struct device_node *np;
-       unsigned int val;
-
-       np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
-       if (!np)
-               goto out;
-
-       l2x0_base = of_iomap(np, 0);
-       if (!l2x0_base) {
-               of_node_put(np);
-               goto out;
-       }
-
-       /* Configure the L2 PREFETCH and POWER registers */
-       val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
-       val |= 0x70800000;
-       writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
-       val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
-       writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
-
-       iounmap(l2x0_base);
-       of_node_put(np);
-
-out:
-       l2x0_of_init(0, ~0UL);
-}
-#else
-static inline void imx6q_init_l2cache(void) {}
-#endif
-
 static void __init imx6q_init_irq(void)
 {
        imx6q_init_revision();
-       imx6q_init_l2cache();
+       imx_init_l2cache();
        imx_src_init();
        imx_gpc_init();
        irqchip_init();
index 132db2609507f44f4806583069123e557ff76e9d..0d75dc54f71508fa48cf3a3096931aed8db31bce 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/irqchip.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
@@ -26,7 +25,7 @@ static void __init imx6sl_init_machine(void)
 
 static void __init imx6sl_init_irq(void)
 {
-       l2x0_of_init(0, ~0UL);
+       imx_init_l2cache();
        imx_src_init();
        imx_gpc_init();
        irqchip_init();
index cf193d87274ac316674dfb4d0e50ccc81adbf4f0..a8229b7f10bf0bf2380e747d8194b1c35f5bed18 100644 (file)
@@ -153,10 +153,10 @@ void __init imx51_soc_init(void)
 void __init imx51_init_late(void)
 {
        mx51_neon_fixup();
-       imx51_pm_init();
+       imx5_pm_init();
 }
 
 void __init imx53_init_late(void)
 {
-       imx53_pm_init();
+       imx5_pm_init();
 }
index 82e79c658eb263a0e261dbae36d712f431ad25d0..58aeaf5baaf62f24368b1b646e57aee867282d03 100644 (file)
@@ -169,14 +169,9 @@ static int __init imx5_pm_common_init(void)
        return imx5_cpuidle_init();
 }
 
-void __init imx51_pm_init(void)
+void __init imx5_pm_init(void)
 {
        int ret = imx5_pm_common_init();
        if (!ret)
                suspend_set_ops(&mx5_suspend_ops);
 }
-
-void __init imx53_pm_init(void)
-{
-       imx5_pm_common_init();
-}
index 6fe81bb4d3c9641cd50d48e2944b8bfad71a0fe2..64ff37ea72b17455a1b5be7600ff7a1c16ceab16 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/system_misc.h>
 #include <asm/proc-fns.h>
 #include <asm/mach-types.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include "common.h"
 #include "hardware.h"
@@ -95,3 +96,35 @@ void __init mxc_arch_reset_init_dt(void)
 
        clk_prepare(wdog_clk);
 }
+
+#ifdef CONFIG_CACHE_L2X0
+void __init imx_init_l2cache(void)
+{
+       void __iomem *l2x0_base;
+       struct device_node *np;
+       unsigned int val;
+
+       np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
+       if (!np)
+               goto out;
+
+       l2x0_base = of_iomap(np, 0);
+       if (!l2x0_base) {
+               of_node_put(np);
+               goto out;
+       }
+
+       /* Configure the L2 PREFETCH and POWER registers */
+       val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
+       val |= 0x70800000;
+       writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
+       val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
+       writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
+
+       iounmap(l2x0_base);
+       of_node_put(np);
+
+out:
+       l2x0_of_init(0, ~0UL);
+}
+#endif
index 8752dbbc6135e448cdc0fb66318c7e0a5104a274..ad05ce60c1c97a052c11713f18532836829831cc 100644 (file)
@@ -17,6 +17,7 @@
 
 #define PHY_ID_KSZ8873MLL      0x000e7237
 #define PHY_ID_KSZ9021         0x00221610
+#define PHY_ID_KSZ9021RLRN     0x00221611
 #define PHY_ID_KS8737          0x00221720
 #define PHY_ID_KSZ8021         0x00221555
 #define PHY_ID_KSZ8031         0x00221556
@@ -35,4 +36,9 @@
 /* struct phy_device dev_flags definitions */
 #define MICREL_PHY_50MHZ_CLK   0x00000001
 
+#define MICREL_KSZ9021_EXTREG_CTRL     0xB
+#define MICREL_KSZ9021_EXTREG_DATA_WRITE       0xC
+#define MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW 0x104
+#define MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW  0x105
+
 #endif /* _MICREL_PHY_H */