cpu.c 2.81 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * Copyright (C) 2015
 * Purna Chandra Mandal <purna.mandal@microchip.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 */
#include <common.h>
9 10 11 12 13
#include <clk.h>
#include <dm.h>
#include <mach/pic32.h>
#include <mach/ddr.h>
#include <dt-bindings/clock/microchip,clock.h>
14

15 16 17 18 19 20 21 22 23 24 25
/* Flash prefetch */
#define PRECON          0x00

/* Flash ECCCON */
#define ECC_MASK	0x03
#define ECC_SHIFT	4

#define CLK_MHZ(x)	((x) / 1000000)

DECLARE_GLOBAL_DATA_PTR;

26
static ulong rate(int id)
27 28 29
{
	int ret;
	struct udevice *dev;
30 31
	struct clk clk;
	ulong rate;
32 33 34

	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
	if (ret) {
35
		printf("clk-uclass not found\n");
36 37 38
		return 0;
	}

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
	clk.id = id;
	ret = clk_request(dev, &clk);
	if (ret < 0)
		return ret;

	rate = clk_get_rate(&clk);

	clk_free(&clk);

	return rate;
}

static ulong clk_get_cpu_rate(void)
{
	return rate(PB7CLK);
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 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 111 112
}

/* initialize prefetch module related to cpu_clk */
static void prefetch_init(void)
{
	struct pic32_reg_atomic *regs;
	const void __iomem *base;
	int v, nr_waits;
	ulong rate;

	/* cpu frequency in MHZ */
	rate = clk_get_cpu_rate() / 1000000;

	/* get flash ECC type */
	base = pic32_get_syscfg_base();
	v = (readl(base + CFGCON) >> ECC_SHIFT) & ECC_MASK;

	if (v < 2) {
		if (rate < 66)
			nr_waits = 0;
		else if (rate < 133)
			nr_waits = 1;
		else
			nr_waits = 2;
	} else {
		if (rate <= 83)
			nr_waits = 0;
		else if (rate <= 166)
			nr_waits = 1;
		else
			nr_waits = 2;
	}

	regs = ioremap(PREFETCH_BASE + PRECON, sizeof(*regs));
	writel(nr_waits, &regs->raw);

	/* Enable prefetch for all */
	writel(0x30, &regs->set);
	iounmap(regs);
}

/* arch specific CPU init after DM */
int arch_cpu_init_dm(void)
{
	/* flash prefetch */
	prefetch_init();
	return 0;
}

/* Un-gate DDR2 modules (gated by default) */
static void ddr2_pmd_ungate(void)
{
	void __iomem *regs;

	regs = pic32_get_syscfg_base();
	writel(0, regs + PMD7);
}

/* initialize the DDR2 Controller and DDR2 PHY */
113 114
phys_size_t initdram(int board_type)
{
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
	ddr2_pmd_ungate();
	ddr2_phy_init();
	ddr2_ctrl_init();
	return ddr2_calculate_size();
}

int misc_init_r(void)
{
	set_io_port_base(0);
	return 0;
}

#ifdef CONFIG_DISPLAY_BOARDINFO
const char *get_core_name(void)
{
	u32 proc_id;
	const char *str;

	proc_id = read_c0_prid();
	switch (proc_id) {
	case 0x19e28:
		str = "PIC32MZ[DA]";
		break;
	default:
		str = "UNKNOWN";
	}

	return str;
}
#endif
#ifdef CONFIG_CMD_CLK
146

147 148
int soc_clk_dump(void)
{
149
	int i;
150 151

	printf("PLL Speed: %lu MHz\n",
152 153 154 155 156
	       CLK_MHZ(rate(PLLCLK)));

	printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK)));

	printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL)));
157 158 159

	for (i = PB1CLK; i <= PB7CLK; i++)
		printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1,
160
		       CLK_MHZ(rate(i)));
161 162 163

	for (i = REF1CLK; i <= REF5CLK; i++)
		printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1,
164
		       CLK_MHZ(rate(i)));
165 166
	return 0;
}
167
#endif