1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2015
4 * Purna Chandra Mandal <purna.mandal@microchip.com>
5 *
6 */
7#include <clk.h>
8#include <dm.h>
9#include <event.h>
10#include <init.h>
11#include <malloc.h>
12#include <asm/global_data.h>
13#include <mach/pic32.h>
14#include <mach/ddr.h>
15#include <dt-bindings/clock/microchip,clock.h>
16
17/* Flash prefetch */
18#define PRECON          0x00
19
20/* Flash ECCCON */
21#define ECC_MASK	0x03
22#define ECC_SHIFT	4
23
24#define CLK_MHZ(x)	((x) / 1000000)
25
26DECLARE_GLOBAL_DATA_PTR;
27
28static ulong rate(int id)
29{
30	int ret;
31	struct udevice *dev;
32	struct clk clk;
33
34	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
35	if (ret) {
36		printf("clk-uclass not found\n");
37		return 0;
38	}
39
40	clk.id = id;
41	ret = clk_request(dev, &clk);
42	if (ret < 0)
43		return ret;
44
45	return clk_get_rate(&clk);
46}
47
48static ulong clk_get_cpu_rate(void)
49{
50	return rate(PB7CLK);
51}
52
53/* initialize prefetch module related to cpu_clk */
54static int prefetch_init(void)
55{
56	struct pic32_reg_atomic *regs;
57	const void __iomem *base;
58	int v, nr_waits;
59	ulong rate;
60
61	/* cpu frequency in MHZ */
62	rate = clk_get_cpu_rate() / 1000000;
63
64	/* get flash ECC type */
65	base = pic32_get_syscfg_base();
66	v = (readl(base + CFGCON) >> ECC_SHIFT) & ECC_MASK;
67
68	if (v < 2) {
69		if (rate < 66)
70			nr_waits = 0;
71		else if (rate < 133)
72			nr_waits = 1;
73		else
74			nr_waits = 2;
75	} else {
76		if (rate <= 83)
77			nr_waits = 0;
78		else if (rate <= 166)
79			nr_waits = 1;
80		else
81			nr_waits = 2;
82	}
83
84	regs = ioremap(PREFETCH_BASE + PRECON, sizeof(*regs));
85	writel(nr_waits, &regs->raw);
86
87	/* Enable prefetch for all */
88	writel(0x30, &regs->set);
89	iounmap(regs);
90
91	return 0;
92}
93
94/* arch-specific CPU init after DM: flash prefetch */
95EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_F, prefetch_init);
96
97/* Un-gate DDR2 modules (gated by default) */
98static void ddr2_pmd_ungate(void)
99{
100	void __iomem *regs;
101
102	regs = pic32_get_syscfg_base();
103	writel(0, regs + PMD7);
104}
105
106/* initialize the DDR2 Controller and DDR2 PHY */
107int dram_init(void)
108{
109	ddr2_pmd_ungate();
110	ddr2_phy_init();
111	ddr2_ctrl_init();
112	gd->ram_size = ddr2_calculate_size();
113
114	return 0;
115}
116
117int misc_init_r(void)
118{
119	set_io_port_base(0);
120	return 0;
121}
122
123#ifdef CONFIG_DISPLAY_BOARDINFO
124const char *get_core_name(void)
125{
126	u32 proc_id;
127	const char *str;
128
129	proc_id = read_c0_prid();
130	switch (proc_id) {
131	case 0x19e28:
132		str = "PIC32MZ[DA]";
133		break;
134	default:
135		str = "UNKNOWN";
136	}
137
138	return str;
139}
140#endif
141