diff options
| -rw-r--r-- | Documentation/devicetree/bindings/clock/imx6q-clock.txt | 3 | ||||
| -rw-r--r-- | arch/arm/mach-imx/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/mach-imx/clk-imx6q.c | 16 | ||||
| -rw-r--r-- | arch/arm/mach-imx/pm-imx6.c | 28 |
4 files changed, 48 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index dd8d8cfe4833..f53f2e5d34e8 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt | |||
| @@ -220,6 +220,9 @@ clocks and IDs. | |||
| 220 | ldb_di0_div_sel 207 | 220 | ldb_di0_div_sel 207 |
| 221 | ldb_di1_div_sel 208 | 221 | ldb_di1_div_sel 208 |
| 222 | pll4_audio_div 209 | 222 | pll4_audio_div 209 |
| 223 | lvds1_sel 210 | ||
| 224 | lvds1_in 211 | ||
| 225 | lvds1_out 212 | ||
| 223 | 226 | ||
| 224 | Examples: | 227 | Examples: |
| 225 | 228 | ||
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 0633cf9cc01f..c26aac0a203d 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
| @@ -809,6 +809,8 @@ config SOC_IMX6Q | |||
| 809 | select HAVE_IMX_SRC | 809 | select HAVE_IMX_SRC |
| 810 | select HAVE_SMP | 810 | select HAVE_SMP |
| 811 | select MFD_SYSCON | 811 | select MFD_SYSCON |
| 812 | select MIGHT_HAVE_PCI | ||
| 813 | select PCI_DOMAINS if PCI | ||
| 812 | select PINCTRL | 814 | select PINCTRL |
| 813 | select PINCTRL_IMX6Q | 815 | select PINCTRL_IMX6Q |
| 814 | select PL310_ERRATA_588369 if CACHE_PL310 | 816 | select PL310_ERRATA_588369 if CACHE_PL310 |
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index f39e7706c5c5..e9f068c646a1 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c | |||
| @@ -58,6 +58,8 @@ static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", | |||
| 58 | static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", | 58 | static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", |
| 59 | "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", | 59 | "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", |
| 60 | "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_aduio_div", }; | 60 | "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_aduio_div", }; |
| 61 | static const char *lvds_sels[] = { "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div", | ||
| 62 | "dummy", "dummy", "pcie_ref", "sata_ref", "usbphy1", "usbphy2", }; | ||
| 61 | static const char *cko2_sels[] = { | 63 | static const char *cko2_sels[] = { |
| 62 | "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", | 64 | "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", |
| 63 | "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi", | 65 | "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi", |
| @@ -105,7 +107,7 @@ enum mx6q_clks { | |||
| 105 | usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow, | 107 | usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow, |
| 106 | spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, gpt_3m, video_27m, | 108 | spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, gpt_3m, video_27m, |
| 107 | ldb_di0_div_7, ldb_di1_div_7, ldb_di0_div_sel, ldb_di1_div_sel, | 109 | ldb_di0_div_7, ldb_di1_div_7, ldb_di0_div_sel, ldb_di1_div_sel, |
| 108 | pll4_audio_div, clk_max | 110 | pll4_audio_div, lvds1_sel, lvds1_in, lvds1_out, clk_max |
| 109 | }; | 111 | }; |
| 110 | 112 | ||
| 111 | static struct clk *clk[clk_max]; | 113 | static struct clk *clk[clk_max]; |
| @@ -170,6 +172,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
| 170 | clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); | 172 | clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); |
| 171 | clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); | 173 | clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); |
| 172 | 174 | ||
| 175 | /* name reg shift width parent_names num_parents */ | ||
| 176 | clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | ||
| 177 | |||
| 173 | /* | 178 | /* |
| 174 | * Bit 20 is the reserved and read-only bit, we do this only for: | 179 | * Bit 20 is the reserved and read-only bit, we do this only for: |
| 175 | * - Do nothing for usbphy clk_enable/disable | 180 | * - Do nothing for usbphy clk_enable/disable |
| @@ -188,6 +193,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
| 188 | 193 | ||
| 189 | clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); | 194 | clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); |
| 190 | clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); | 195 | clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); |
| 196 | /* NOTICE: The gate of the lvds1 in/out is used to select the clk direction */ | ||
| 197 | clk[lvds1_in] = imx_clk_gate("lvds1_in", NULL, base + 0x160, 12); | ||
| 198 | clk[lvds1_out] = imx_clk_gate("lvds1_out", "lvds1_sel", base + 0x160, 10); | ||
| 191 | 199 | ||
| 192 | clk[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); | 200 | clk[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); |
| 193 | clk[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); | 201 | clk[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); |
| @@ -448,6 +456,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
| 448 | */ | 456 | */ |
| 449 | clk_set_parent(clk[enfc_sel], clk[pll2_pfd2_396m]); | 457 | clk_set_parent(clk[enfc_sel], clk[pll2_pfd2_396m]); |
| 450 | 458 | ||
| 459 | /* Set the parent clks of PCIe lvds1 and pcie_axi to be sata ref, axi */ | ||
| 460 | if (clk_set_parent(clk[lvds1_sel], clk[sata_ref])) | ||
| 461 | pr_err("Failed to set PCIe bus parent clk.\n"); | ||
| 462 | if (clk_set_parent(clk[pcie_axi_sel], clk[axi])) | ||
| 463 | pr_err("Failed to set PCIe parent clk.\n"); | ||
| 464 | |||
| 451 | /* gpu clock initilazation */ | 465 | /* gpu clock initilazation */ |
| 452 | clk_set_parent(clk[gpu3d_shader_sel], clk[pll2_pfd1_594m]); | 466 | clk_set_parent(clk[gpu3d_shader_sel], clk[pll2_pfd1_594m]); |
| 453 | clk_set_rate(clk[gpu3d_shader], 594000000); | 467 | clk_set_rate(clk[gpu3d_shader], 594000000); |
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 1f75d059a887..acb32940b39b 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c | |||
| @@ -18,6 +18,9 @@ | |||
| 18 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
| 19 | #include <linux/suspend.h> | 19 | #include <linux/suspend.h> |
| 20 | #include <linux/genalloc.h> | 20 | #include <linux/genalloc.h> |
| 21 | #include <linux/regmap.h> | ||
| 22 | #include <linux/mfd/syscon.h> | ||
| 23 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | ||
| 21 | #include <asm/cacheflush.h> | 24 | #include <asm/cacheflush.h> |
| 22 | #include <asm/fncpy.h> | 25 | #include <asm/fncpy.h> |
| 23 | #include <asm/proc-fns.h> | 26 | #include <asm/proc-fns.h> |
| @@ -229,6 +232,22 @@ static int imx6_suspend_finish(unsigned long val) | |||
| 229 | 232 | ||
| 230 | static int imx6_pm_enter(suspend_state_t state) | 233 | static int imx6_pm_enter(suspend_state_t state) |
| 231 | { | 234 | { |
| 235 | struct regmap *gpr; | ||
| 236 | |||
| 237 | /* | ||
| 238 | * L2 can exit by 'reset' or Inband beacon (from remote EP) | ||
| 239 | * toggling phy_powerdown has same effect as 'inband beacon' | ||
| 240 | * So, toggle bit18 of GPR1, to fix errata | ||
| 241 | * "PCIe PCIe does not support L2 Power Down" | ||
| 242 | */ | ||
| 243 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); | ||
| 244 | if (IS_ERR(gpr)) { | ||
| 245 | pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n"); | ||
| 246 | return PTR_ERR(gpr); | ||
| 247 | } | ||
| 248 | regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD, | ||
| 249 | IMX6Q_GPR1_PCIE_TEST_PD); | ||
| 250 | |||
| 232 | switch (state) { | 251 | switch (state) { |
| 233 | case PM_SUSPEND_STANDBY: | 252 | case PM_SUSPEND_STANDBY: |
| 234 | imx6_set_lpm(STOP_POWER_ON); | 253 | imx6_set_lpm(STOP_POWER_ON); |
| @@ -258,6 +277,15 @@ static int imx6_pm_enter(suspend_state_t state) | |||
| 258 | return -EINVAL; | 277 | return -EINVAL; |
| 259 | } | 278 | } |
| 260 | 279 | ||
| 280 | /* | ||
| 281 | * L2 can exit by 'reset' or Inband beacon (from remote EP) | ||
| 282 | * toggling phy_powerdown has same effect as 'inband beacon' | ||
| 283 | * So, toggle bit18 of GPR1, to fix errata | ||
| 284 | * "PCIe PCIe does not support L2 Power Down" | ||
| 285 | */ | ||
| 286 | regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD, | ||
| 287 | !IMX6Q_GPR1_PCIE_TEST_PD); | ||
| 288 | |||
| 261 | return 0; | 289 | return 0; |
| 262 | } | 290 | } |
| 263 | 291 | ||
