167 lines
4.3 KiB
C
167 lines
4.3 KiB
C
/*
|
|
* Copyright (C) 2015-2016 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/io.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_address.h>
|
|
#include <linux/of_net.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include "hardware.h"
|
|
|
|
unsigned long iram_tlb_base_addr;
|
|
unsigned long iram_tlb_phys_addr;
|
|
|
|
unsigned long save_ttbr1(void)
|
|
{
|
|
unsigned long lttbr1;
|
|
asm volatile(
|
|
".align 4\n"
|
|
"mrc p15, 0, %0, c2, c0, 1\n"
|
|
: "=r" (lttbr1)
|
|
);
|
|
return lttbr1;
|
|
}
|
|
|
|
void restore_ttbr1(unsigned long ttbr1)
|
|
{
|
|
asm volatile(
|
|
".align 4\n"
|
|
"mcr p15, 0, %0, c2, c0, 1\n"
|
|
: : "r" (ttbr1)
|
|
);
|
|
}
|
|
|
|
#define OCOTP_MAC_OFF (cpu_is_imx7d() ? 0x640 : 0x620)
|
|
#define OCOTP_MACn(n) (OCOTP_MAC_OFF + (n) * 0x10)
|
|
void __init imx6_enet_mac_init(const char *enet_compat, const char *ocotp_compat)
|
|
{
|
|
struct device_node *ocotp_np, *enet_np, *from = NULL;
|
|
void __iomem *base;
|
|
struct property *newmac;
|
|
u32 macaddr_low;
|
|
u32 macaddr_high = 0;
|
|
u32 macaddr1_high = 0;
|
|
u8 *macaddr;
|
|
int i, id;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
enet_np = of_find_compatible_node(from, NULL, enet_compat);
|
|
if (!enet_np)
|
|
return;
|
|
|
|
from = enet_np;
|
|
|
|
if (of_get_mac_address(enet_np))
|
|
goto put_enet_node;
|
|
|
|
id = of_alias_get_id(enet_np, "ethernet");
|
|
if (id < 0)
|
|
id = i;
|
|
|
|
ocotp_np = of_find_compatible_node(NULL, NULL, ocotp_compat);
|
|
if (!ocotp_np) {
|
|
pr_warn("failed to find ocotp node\n");
|
|
goto put_enet_node;
|
|
}
|
|
|
|
base = of_iomap(ocotp_np, 0);
|
|
if (!base) {
|
|
pr_warn("failed to map ocotp\n");
|
|
goto put_ocotp_node;
|
|
}
|
|
|
|
macaddr_low = readl_relaxed(base + OCOTP_MACn(1));
|
|
if (id)
|
|
macaddr1_high = readl_relaxed(base + OCOTP_MACn(2));
|
|
else
|
|
macaddr_high = readl_relaxed(base + OCOTP_MACn(0));
|
|
|
|
newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
|
|
if (!newmac)
|
|
goto put_ocotp_node;
|
|
|
|
newmac->value = newmac + 1;
|
|
newmac->length = 6;
|
|
newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
|
|
if (!newmac->name) {
|
|
kfree(newmac);
|
|
goto put_ocotp_node;
|
|
}
|
|
|
|
macaddr = newmac->value;
|
|
if (id) {
|
|
macaddr[5] = (macaddr_low >> 16) & 0xff;
|
|
macaddr[4] = (macaddr_low >> 24) & 0xff;
|
|
macaddr[3] = macaddr1_high & 0xff;
|
|
macaddr[2] = (macaddr1_high >> 8) & 0xff;
|
|
macaddr[1] = (macaddr1_high >> 16) & 0xff;
|
|
macaddr[0] = (macaddr1_high >> 24) & 0xff;
|
|
} else {
|
|
macaddr[5] = macaddr_high & 0xff;
|
|
macaddr[4] = (macaddr_high >> 8) & 0xff;
|
|
macaddr[3] = (macaddr_high >> 16) & 0xff;
|
|
macaddr[2] = (macaddr_high >> 24) & 0xff;
|
|
macaddr[1] = macaddr_low & 0xff;
|
|
macaddr[0] = (macaddr_low >> 8) & 0xff;
|
|
}
|
|
|
|
of_update_property(enet_np, newmac);
|
|
|
|
put_ocotp_node:
|
|
of_node_put(ocotp_np);
|
|
put_enet_node:
|
|
of_node_put(enet_np);
|
|
}
|
|
}
|
|
|
|
#ifndef CONFIG_HAVE_IMX_GPC
|
|
int imx_gpc_mf_request_on(unsigned int irq, unsigned int on) { return 0; }
|
|
EXPORT_SYMBOL_GPL(imx_gpc_mf_request_on);
|
|
#endif
|
|
|
|
#if !defined(CONFIG_SOC_IMX6SL)
|
|
u32 imx6_lpddr2_freq_change_start, imx6_lpddr2_freq_change_end;
|
|
void mx6_lpddr2_freq_change(u32 freq, int bus_freq_mode) {}
|
|
#endif
|
|
|
|
#if !defined(CONFIG_SOC_IMX6SLL)
|
|
void imx6sll_lpddr2_freq_change(u32 freq, int bus_freq_mode) {}
|
|
#endif
|
|
|
|
#if !defined(CONFIG_SOC_IMX6SX) && !defined(CONFIG_SOC_IMX6UL)
|
|
u32 imx6_up_ddr3_freq_change_start, imx6_up_ddr3_freq_change_end;
|
|
struct imx6_busfreq_info {
|
|
} __aligned(8);
|
|
void imx6_up_ddr3_freq_change(struct imx6_busfreq_info *busfreq_info) {}
|
|
void imx6_up_lpddr2_freq_change(u32 freq, int bus_freq_mode) {}
|
|
#endif
|
|
|
|
#if !defined(CONFIG_SOC_IMX6ULL)
|
|
u32 mx6ull_lpm_wfi_start, mx6ull_lpm_wfi_end;
|
|
void imx6ull_low_power_idle(void) {}
|
|
#endif
|
|
|
|
#if !defined(CONFIG_SOC_IMX6Q)
|
|
u32 mx6_ddr3_freq_change_start, mx6_ddr3_freq_change_end;
|
|
u32 mx6q_lpddr2_freq_change_start, mx6q_lpddr2_freq_change_end;
|
|
u32 wfe_smp_freq_change_start, wfe_smp_freq_change_end;
|
|
void mx6_ddr3_freq_change(u32 freq, void *ddr_settings,
|
|
bool dll_mode, void *iomux_offsets) {}
|
|
void mx6q_lpddr2_freq_change(u32 freq, void *ddr_settings) {}
|
|
void wfe_smp_freq_change(u32 cpuid, u32 *ddr_freq_change_done) {}
|
|
#endif
|
|
|
|
#if !defined(CONFIG_SOC_IMX7D)
|
|
void imx7_smp_wfe(u32 cpuid, u32 ocram_base) {}
|
|
void imx7d_ddr3_freq_change(u32 freq) {}
|
|
#endif
|
|
|