mach-imx6q.c 10.1 KB
Newer Older
1
/*
2
 * Copyright 2011-2013 Freescale Semiconductor, Inc.
3 4 5 6 7 8 9 10 11 12
 * Copyright 2011 Linaro Ltd.
 *
 * 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
 */

13 14
#include <linux/clk.h>
#include <linux/clkdev.h>
15
#include <linux/cpu.h>
16
#include <linux/delay.h>
R
Robert Lee 已提交
17
#include <linux/export.h>
18
#include <linux/init.h>
19
#include <linux/io.h>
20
#include <linux/irq.h>
21
#include <linux/irqchip.h>
22
#include <linux/of.h>
23
#include <linux/of_address.h>
24 25
#include <linux/of_irq.h>
#include <linux/of_platform.h>
26
#include <linux/pm_opp.h>
27
#include <linux/pci.h>
28
#include <linux/phy.h>
29
#include <linux/reboot.h>
30
#include <linux/regmap.h>
31
#include <linux/micrel_phy.h>
32
#include <linux/mfd/syscon.h>
33
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
34
#include <asm/mach/arch.h>
35
#include <asm/mach/map.h>
36
#include <asm/system_misc.h>
37

38
#include "common.h"
39
#include "cpuidle.h"
40
#include "hardware.h"
R
Robert Lee 已提交
41

42 43 44
/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
static int ksz9021rn_phy_fixup(struct phy_device *phydev)
{
45
	if (IS_BUILTIN(CONFIG_PHYLIB)) {
46
		/* min rx data delay */
47 48 49
		phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
			0x8000 | MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW);
		phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0x0000);
50

51
		/* max rx/tx clock delay, min rx/tx control delay */
52 53 54 55 56
		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);
57
	}
58 59 60 61

	return 0;
}

62
static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
63
{
64 65 66 67
	phy_write(dev, 0x0d, device);
	phy_write(dev, 0x0e, reg);
	phy_write(dev, 0x0d, (1 << 14) | device);
	phy_write(dev, 0x0e, val);
68 69
}

70
static int ksz9031rn_phy_fixup(struct phy_device *dev)
71
{
72 73 74 75 76 77 78 79 80
	/*
	 * 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;
81 82
}

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
/*
 * fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High
 * as they are used for slots1-7 PERST#
 */
static void ventana_pciesw_early_fixup(struct pci_dev *dev)
{
	u32 dw;

	if (!of_machine_is_compatible("gw,ventana"))
		return;

	if (dev->devfn != 0)
		return;

	pci_read_config_dword(dev, 0x62c, &dw);
	dw |= 0xaaa8; // GPIO1-7 outputs
	pci_write_config_dword(dev, 0x62c, dw);

	pci_read_config_dword(dev, 0x644, &dw);
	dw |= 0xfe;   // GPIO1-7 output high
	pci_write_config_dword(dev, 0x644, dw);

	msleep(100);
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup);

111
static int ar8031_phy_fixup(struct phy_device *dev)
112
{
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
	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;
132 133
}

134 135
#define PHY_ID_AR8031	0x004dd074

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
static int ar8035_phy_fixup(struct phy_device *dev)
{
	u16 val;

	/* Ar803x phy SmartEEE feature cause link status generates glitch,
	 * which cause ethernet link down/up issue, so disable SmartEEE
	 */
	phy_write(dev, 0xd, 0x3);
	phy_write(dev, 0xe, 0x805d);
	phy_write(dev, 0xd, 0x4003);

	val = phy_read(dev, 0xe);
	phy_write(dev, 0xe, val & ~(1 << 8));

	/*
	 * Enable 125MHz clock from CLK_25M on the AR8031.  This
	 * is fed in to the IMX6 on the ENET_REF_CLK (V22) pad.
	 * Also, introduce a tx clock delay.
	 *
	 * This is the same as is the AR8031 fixup.
	 */
	ar8031_phy_fixup(dev);

	/*check phy power*/
	val = phy_read(dev, 0x0);
	if (val & BMCR_PDOWN)
		phy_write(dev, 0x0, val & ~BMCR_PDOWN);

	return 0;
}

#define PHY_ID_AR8035 0x004dd072

169
static void __init imx6q_enet_phy_init(void)
170
{
171
	if (IS_BUILTIN(CONFIG_PHYLIB)) {
172
		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
173
				ksz9021rn_phy_fixup);
174 175
		phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
				ksz9031rn_phy_fixup);
176 177
		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
				ar8031_phy_fixup);
178 179
		phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef,
				ar8035_phy_fixup);
180
	}
181 182
}

183 184
static void __init imx6q_1588_init(void)
{
185 186 187
	struct device_node *np;
	struct clk *ptp_clk;
	struct clk *enet_ref;
188
	struct regmap *gpr;
189
	u32 clksel;
190

191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-fec");
	if (!np) {
		pr_warn("%s: failed to find fec node\n", __func__);
		return;
	}

	ptp_clk = of_clk_get(np, 2);
	if (IS_ERR(ptp_clk)) {
		pr_warn("%s: failed to get ptp clock\n", __func__);
		goto put_node;
	}

	enet_ref = clk_get_sys(NULL, "enet_ref");
	if (IS_ERR(enet_ref)) {
		pr_warn("%s: failed to get enet clock\n", __func__);
		goto put_ptp_clk;
	}

	/*
	 * If enet_ref from ANATOP/CCM is the PTP clock source, we need to
	 * set bit IOMUXC_GPR1[21].  Or the PTP clock must be from pad
	 * (external OSC), and we need to clear the bit.
	 */
214 215 216
	clksel = clk_is_match(ptp_clk, enet_ref) ?
				IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
				IMX6Q_GPR1_ENET_CLK_SEL_PAD;
217 218
	gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
	if (!IS_ERR(gpr))
219 220
		regmap_update_bits(gpr, IOMUXC_GPR1,
				IMX6Q_GPR1_ENET_CLK_SEL_MASK,
221
				clksel);
222 223 224
	else
		pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");

225 226 227 228 229
	clk_put(enet_ref);
put_ptp_clk:
	clk_put(ptp_clk);
put_node:
	of_node_put(np);
230
}
231

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
static void __init imx6q_axi_init(void)
{
	struct regmap *gpr;
	unsigned int mask;

	gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
	if (!IS_ERR(gpr)) {
		/*
		 * Enable the cacheable attribute of VPU and IPU
		 * AXI transactions.
		 */
		mask = IMX6Q_GPR4_VPU_WR_CACHE_SEL |
			IMX6Q_GPR4_VPU_RD_CACHE_SEL |
			IMX6Q_GPR4_VPU_P_WR_CACHE_VAL |
			IMX6Q_GPR4_VPU_P_RD_CACHE_VAL_MASK |
			IMX6Q_GPR4_IPU_WR_CACHE_CTL |
			IMX6Q_GPR4_IPU_RD_CACHE_CTL;
		regmap_update_bits(gpr, IOMUXC_GPR4, mask, mask);

		/* Increase IPU read QoS priority */
		regmap_update_bits(gpr, IOMUXC_GPR6,
				IMX6Q_GPR6_IPU1_ID00_RD_QOS_MASK |
				IMX6Q_GPR6_IPU1_ID01_RD_QOS_MASK,
				(0xf << 16) | (0x7 << 20));
		regmap_update_bits(gpr, IOMUXC_GPR7,
				IMX6Q_GPR7_IPU2_ID00_RD_QOS_MASK |
				IMX6Q_GPR7_IPU2_ID01_RD_QOS_MASK,
				(0xf << 16) | (0x7 << 20));
	} else {
		pr_warn("failed to find fsl,imx6q-iomuxc-gpr regmap\n");
	}
}

265 266
static void __init imx6q_init_machine(void)
{
267 268
	struct device *parent;

269 270 271 272 273
	if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)
		imx_print_silicon_rev("i.MX6QP", IMX_CHIP_REVISION_1_0);
	else
		imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
				imx_get_soc_revision());
274

275 276 277 278
	parent = imx_soc_device_init();
	if (parent == NULL)
		pr_warn("failed to initialize soc device\n");

279
	imx6q_enet_phy_init();
280

281
	of_platform_default_populate(NULL, NULL, parent);
282

283
	imx_anatop_init();
284
	cpu_is_imx6q() ?  imx6q_pm_init() : imx6dl_pm_init();
285
	imx6q_1588_init();
286
	imx6q_axi_init();
287 288
}

289 290 291
#define OCOTP_CFG3			0x440
#define OCOTP_CFG3_SPEED_SHIFT		16
#define OCOTP_CFG3_SPEED_1P2GHZ		0x3
292 293
#define OCOTP_CFG3_SPEED_996MHZ		0x2
#define OCOTP_CFG3_SPEED_852MHZ		0x1
294

295
static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
{
	struct device_node *np;
	void __iomem *base;
	u32 val;

	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
	if (!np) {
		pr_warn("failed to find ocotp node\n");
		return;
	}

	base = of_iomap(np, 0);
	if (!base) {
		pr_warn("failed to map ocotp\n");
		goto put_node;
	}

313 314 315 316 317 318 319 320
	/*
	 * SPEED_GRADING[1:0] defines the max speed of ARM:
	 * 2b'11: 1200000000Hz;
	 * 2b'10: 996000000Hz;
	 * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
	 * 2b'00: 792000000Hz;
	 * We need to set the max speed of ARM according to fuse map.
	 */
321 322
	val = readl_relaxed(base + OCOTP_CFG3);
	val >>= OCOTP_CFG3_SPEED_SHIFT;
323 324
	val &= 0x3;

325
	if ((val != OCOTP_CFG3_SPEED_1P2GHZ) && cpu_is_imx6q())
326
		if (dev_pm_opp_disable(cpu_dev, 1200000000))
327
			pr_warn("failed to disable 1.2 GHz OPP\n");
328 329 330 331 332 333 334 335
	if (val < OCOTP_CFG3_SPEED_996MHZ)
		if (dev_pm_opp_disable(cpu_dev, 996000000))
			pr_warn("failed to disable 996 MHz OPP\n");
	if (cpu_is_imx6q()) {
		if (val != OCOTP_CFG3_SPEED_852MHZ)
			if (dev_pm_opp_disable(cpu_dev, 852000000))
				pr_warn("failed to disable 852 MHz OPP\n");
	}
336
	iounmap(base);
337 338 339 340
put_node:
	of_node_put(np);
}

341
static void __init imx6q_opp_init(void)
342 343
{
	struct device_node *np;
344
	struct device *cpu_dev = get_cpu_device(0);
345

346 347 348 349
	if (!cpu_dev) {
		pr_warn("failed to get cpu0 device\n");
		return;
	}
350
	np = of_node_get(cpu_dev->of_node);
351 352 353 354 355
	if (!np) {
		pr_warn("failed to find cpu0 node\n");
		return;
	}

356
	if (dev_pm_opp_of_add_table(cpu_dev)) {
357 358 359 360
		pr_warn("failed to init OPP table\n");
		goto put_node;
	}

361
	imx6q_opp_check_speed_grading(cpu_dev);
362 363 364 365 366

put_node:
	of_node_put(np);
}

367
static struct platform_device imx6q_cpufreq_pdev = {
368 369 370
	.name = "imx6q-cpufreq",
};

R
Robert Lee 已提交
371 372
static void __init imx6q_init_late(void)
{
373 374 375 376
	/*
	 * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
	 * to run cpuidle on them.
	 */
377
	if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
378
		imx6q_cpuidle_init();
379 380

	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
381
		imx6q_opp_init();
382 383
		platform_device_register(&imx6q_cpufreq_pdev);
	}
R
Robert Lee 已提交
384 385
}

386 387
static void __init imx6q_map_io(void)
{
388
	debug_ll_io_init();
389 390 391 392 393
	imx_scu_map_io();
}

static void __init imx6q_init_irq(void)
{
394
	imx_gpc_check_dt();
395
	imx_init_revision_from_anatop();
396
	imx_init_l2cache();
397
	imx_src_init();
398
	irqchip_init();
399
	imx6_pm_ccm_init("fsl,imx6q-ccm");
400 401
}

S
Shawn Guo 已提交
402
static const char * const imx6q_dt_compat[] __initconst = {
S
Shawn Guo 已提交
403
	"fsl,imx6dl",
404
	"fsl,imx6q",
405
	"fsl,imx6qp",
406 407 408
	NULL,
};

S
Shawn Guo 已提交
409
DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
410 411
	.l2c_aux_val 	= 0,
	.l2c_aux_mask	= ~0,
412
	.smp		= smp_ops(imx_smp_ops),
413 414 415
	.map_io		= imx6q_map_io,
	.init_irq	= imx6q_init_irq,
	.init_machine	= imx6q_init_machine,
R
Robert Lee 已提交
416
	.init_late      = imx6q_init_late,
417 418
	.dt_compat	= imx6q_dt_compat,
MACHINE_END