1614 lines
44 KiB
C
1614 lines
44 KiB
C
/* $NetBSD: imx7_ccm.c,v 1.2 2016/10/20 16:50:11 ryo Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2010-2012, 2014 Genetec Corporation. All rights reserved.
|
|
* Written by Hashimoto Kenichi for Genetec Corporation.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/*
|
|
* Clock Controller Module (CCM) for i.MX7
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__KERNEL_RCSID(0, "$NetBSD: imx7_ccm.c,v 1.2 2016/10/20 16:50:11 ryo Exp $");
|
|
|
|
#include "opt_imx.h"
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <sys/bus.h>
|
|
#include <sys/device.h>
|
|
#include <sys/sysctl.h>
|
|
#include <sys/cpufreq.h>
|
|
#include <sys/malloc.h>
|
|
#include <sys/param.h>
|
|
|
|
#include <machine/cpu.h>
|
|
#include <arm/imx/imx7_ccmvar.h>
|
|
#include <arm/imx/imx7_ccmreg.h>
|
|
#include <arm/imx/imx7var.h>
|
|
#include <arm/imx/imx7reg.h>
|
|
|
|
#ifdef CCM_DEBUG
|
|
int ccm_debug = 1;
|
|
#endif
|
|
|
|
struct imxccm_softc {
|
|
device_t sc_dev;
|
|
bus_space_tag_t sc_iot;
|
|
bus_space_handle_t sc_ioh;
|
|
bus_space_handle_t sc_ioh_analog;
|
|
|
|
/* for sysctl */
|
|
struct sysctllog *sc_log;
|
|
int sc_sysctlnode_arm_pll;
|
|
int sc_sysctlnode_sys_pll;
|
|
int sc_sysctlnode_enet_pll;
|
|
int sc_sysctlnode_audio_pll;
|
|
int sc_sysctlnode_video_pll;
|
|
int sc_sysctlnode_ddr_pll;
|
|
int sc_sysctlnode_usb_pll;
|
|
|
|
int sc_sysctlnode_arm_a7_clk;
|
|
int sc_sysctlnode_arm_m4_clk;
|
|
};
|
|
|
|
const struct imx7clkroottbl {
|
|
int clksrc[8];
|
|
uint32_t targetroot;
|
|
int type;
|
|
#define CLKTYPE_CORE 0
|
|
#define CLKTYPE_DRAM 1
|
|
#define CLKTYPE_DRAM_PHYM 2
|
|
#define CLKTYPE_IP 3
|
|
#define CLKTYPE_AHB 4
|
|
#define CLKTYPE_BUS 5
|
|
} imx7clkroottbl[] = {
|
|
[IMX7CLK_ARM_A7_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ARM_A7_CLK_ROOT,
|
|
.type = CLKTYPE_CORE,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ARM_PLL,
|
|
IMX7CLK_ENET_PLL_DIV2, IMX7CLK_DDR_PLL,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_SYS_PLL_PFD0,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ARM_M4_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ARM_M4_CLK_ROOT,
|
|
.type = CLKTYPE_BUS,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV4, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_MAIN_AXI_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_MAIN_AXI_CLK_ROOT,
|
|
.type = CLKTYPE_BUS,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD1,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL_PFD5, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_DISP_AXI_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_DISP_AXI_CLK_ROOT,
|
|
.type = CLKTYPE_BUS,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD1,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL_PFD6, IMX7CLK_SYS_PLL_PFD7,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ENET_AXI_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ENET_AXI_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL_DIV2, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_SYS_PLL_PFD4
|
|
}
|
|
},
|
|
[IMX7CLK_NAND_USDHC_BUS_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_NAND_USDHC_BUS_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_AHB_CLK_ROOT,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD2_DIV2, IMX7CLK_SYS_PLL_PFD6,
|
|
IMX7CLK_ENET_PLL_DIV4, IMX7CLK_AUDIO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_AHB_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_AHB_CLK_ROOT,
|
|
.type = CLKTYPE_AHB,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_SYS_PLL_PFD0,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_USB_PLL,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_IPG_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_IPG_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_AHB_CLK_ROOT, -1,
|
|
-1, -1,
|
|
-1, -1,
|
|
-1, -1
|
|
}
|
|
},
|
|
[IMX7CLK_DRAM_PHYM_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_DRAM_PHYM_CLK_ROOT,
|
|
.type = CLKTYPE_DRAM_PHYM,
|
|
.clksrc = {
|
|
IMX7CLK_DDR_PLL, IMX7CLK_DRAM_PHYM_ALT_CLK_ROOT,
|
|
-1, -1,
|
|
-1, -1,
|
|
-1, -1
|
|
}
|
|
},
|
|
[IMX7CLK_DRAM_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_DRAM_CLK_ROOT,
|
|
.type = CLKTYPE_DRAM,
|
|
.clksrc = {
|
|
IMX7CLK_DDR_PLL, IMX7CLK_DRAM_ALT_CLK_ROOT,
|
|
-1, -1,
|
|
-1, -1,
|
|
-1, -1
|
|
}
|
|
},
|
|
[IMX7CLK_DRAM_PHYM_ALT_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_DRAM_PHYM_ALT_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_USB_PLL, IMX7CLK_SYS_PLL_PFD7,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_DRAM_ALT_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_DRAM_ALT_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_ENET_PLL_DIV4,
|
|
IMX7CLK_USB_PLL, IMX7CLK_SYS_PLL_PFD0,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_SYS_PLL_PFD2
|
|
}
|
|
},
|
|
[IMX7CLK_USB_HSIC_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_USB_HSIC_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_USB_PLL, IMX7CLK_SYS_PLL_PFD3,
|
|
IMX7CLK_SYS_PLL_PFD4, IMX7CLK_SYS_PLL_PFD5,
|
|
IMX7CLK_SYS_PLL_PFD6, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_PCIE_CTRL_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_PCIE_CTRL_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL_DIV2, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD1, IMX7CLK_SYS_PLL_PFD6
|
|
}
|
|
},
|
|
[IMX7CLK_PCIE_PHY_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_PCIE_PHY_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_ENET_PLL_DIV2, IMX7CLK_EXT_CLK1,
|
|
IMX7CLK_EXT_CLK2, IMX7CLK_EXT_CLK3,
|
|
IMX7CLK_EXT_CLK4, IMX7CLK_SYS_PLL_PFD0
|
|
}
|
|
},
|
|
[IMX7CLK_EPDC_PIXEL_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_EPDC_PIXEL_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD1,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_SYS_PLL_PFD5, IMX7CLK_SYS_PLL_PFD6,
|
|
IMX7CLK_SYS_PLL_PFD7, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_LCDIF_PIXEL_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_LCDIF_PIXEL_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD5,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_EXT_CLK3,
|
|
IMX7CLK_SYS_PLL_PFD4, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_MIPI_DSI_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_MIPI_DSI_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD5,
|
|
IMX7CLK_SYS_PLL_PFD3, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_SYS_PLL_PFD0_DIV2, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_AUDIO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_MIPI_CSI_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_MIPI_CSI_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_SYS_PLL_PFD3, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_SYS_PLL_PFD0_DIV2, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_AUDIO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_MIPI_DPHY_REF_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_MIPI_DPHY_REF_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_SYS_PLL_PFD5,
|
|
IMX7CLK_REF_1M, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_EXT_CLK3
|
|
}
|
|
},
|
|
[IMX7CLK_SAI1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_SAI1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_EXT_CLK2
|
|
}
|
|
},
|
|
[IMX7CLK_SAI2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_SAI2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_EXT_CLK2
|
|
}
|
|
},
|
|
[IMX7CLK_SAI3_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_SAI3_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_EXT_CLK3
|
|
}
|
|
},
|
|
[IMX7CLK_ENET1_REF_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ENET1_REF_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV8,
|
|
IMX7CLK_ENET_PLL_DIV20, IMX7CLK_ENET_PLL_DIV40,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_EXT_CLK4
|
|
}
|
|
},
|
|
[IMX7CLK_ENET1_TIME_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ENET1_TIME_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK1,
|
|
IMX7CLK_EXT_CLK2, IMX7CLK_EXT_CLK3,
|
|
IMX7CLK_EXT_CLK4, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ENET2_REF_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ENET2_REF_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV8,
|
|
IMX7CLK_ENET_PLL_DIV20, IMX7CLK_ENET_PLL_DIV40,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_EXT_CLK4
|
|
}
|
|
},
|
|
[IMX7CLK_ENET2_TIME_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ENET2_TIME_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK1,
|
|
IMX7CLK_EXT_CLK2, IMX7CLK_EXT_CLK3,
|
|
IMX7CLK_EXT_CLK4, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ENET_PHY_REF_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ENET_PHY_REF_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV40,
|
|
IMX7CLK_ENET_PLL_DIV20, IMX7CLK_ENET_PLL_DIV8,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_SYS_PLL_PFD3
|
|
}
|
|
},
|
|
[IMX7CLK_EIM_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_EIM_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD2, IMX7CLK_SYS_PLL_PFD3,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_NAND_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_NAND_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_SYS_PLL_PFD0,
|
|
IMX7CLK_SYS_PLL_PFD3, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV4, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_QSPI_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_QSPI_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD3, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_SYS_PLL_PFD6, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_USDHC1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_USDHC1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD0,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD4, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_SYS_PLL_PFD6, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_USDHC2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_USDHC2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD0,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD4, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_SYS_PLL_PFD6, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_USDHC3_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_USDHC3_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD0,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD4, IMX7CLK_SYS_PLL_PFD2,
|
|
IMX7CLK_SYS_PLL_PFD6, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_CAN1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_CAN1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_USB_PLL,
|
|
IMX7CLK_EXT_CLK1, IMX7CLK_EXT_CLK4
|
|
}
|
|
},
|
|
[IMX7CLK_CAN2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_CAN2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_USB_PLL,
|
|
IMX7CLK_EXT_CLK1, IMX7CLK_EXT_CLK3
|
|
}
|
|
},
|
|
[IMX7CLK_I2C1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_I2C1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_ENET_PLL_DIV20, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_VIDEO_PLL,
|
|
IMX7CLK_USB_PLL, IMX7CLK_SYS_PLL_PFD2_DIV2
|
|
}
|
|
},
|
|
[IMX7CLK_I2C2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_I2C2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_ENET_PLL_DIV20, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_VIDEO_PLL,
|
|
IMX7CLK_USB_PLL, IMX7CLK_SYS_PLL_PFD2_DIV2
|
|
}
|
|
},
|
|
[IMX7CLK_I2C3_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_I2C3_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_ENET_PLL_DIV20, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_VIDEO_PLL,
|
|
IMX7CLK_USB_PLL, IMX7CLK_SYS_PLL_PFD2_DIV2
|
|
}
|
|
},
|
|
[IMX7CLK_I2C4_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_I2C4_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_ENET_PLL_DIV20, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_VIDEO_PLL,
|
|
IMX7CLK_USB_PLL, IMX7CLK_SYS_PLL_PFD2_DIV2
|
|
}
|
|
},
|
|
[IMX7CLK_UART1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_UART1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_EXT_CLK4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_UART2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_UART2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_EXT_CLK3, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_UART3_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_UART3_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_EXT_CLK4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_UART4_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_UART4_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_EXT_CLK3, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_UART5_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_UART5_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_EXT_CLK4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_UART6_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_UART6_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_EXT_CLK3, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_UART7_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_UART7_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_EXT_CLK4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ECSPI1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ECSPI1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_ENET_PLL_DIV4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ECSPI2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ECSPI2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_ENET_PLL_DIV4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ECSPI3_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ECSPI3_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_ENET_PLL_DIV4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_ECSPI4_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_ECSPI4_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV25, IMX7CLK_SYS_PLL_DIV4,
|
|
IMX7CLK_SYS_PLL, IMX7CLK_SYS_PLL_PFD4,
|
|
IMX7CLK_ENET_PLL_DIV4, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_PWM1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_PWM1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK1,
|
|
IMX7CLK_REF_1M, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_PWM2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_PWM2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK1,
|
|
IMX7CLK_REF_1M, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_PWM3_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_PWM3_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_REF_1M, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_PWM4_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_PWM4_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK2,
|
|
IMX7CLK_REF_1M, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_FLEXTIMER1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_FLEXTIMER1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK3,
|
|
IMX7CLK_REF_1M, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_FLEXTIMER2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_FLEXTIMER2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK3,
|
|
IMX7CLK_REF_1M, IMX7CLK_VIDEO_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_SIM1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_SIM1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_USB_PLL, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_SIM2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_SIM2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_USB_PLL, IMX7CLK_VIDEO_PLL,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_SYS_PLL_PFD7
|
|
}
|
|
},
|
|
[IMX7CLK_GPT1_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_GPT1_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_PFD0, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_REF_1M,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK1
|
|
}
|
|
},
|
|
[IMX7CLK_GPT2_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_GPT2_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_PFD0, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_REF_1M,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK2
|
|
}
|
|
},
|
|
[IMX7CLK_GPT3_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_GPT3_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_PFD0, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_REF_1M,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK3
|
|
}
|
|
},
|
|
[IMX7CLK_GPT4_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_GPT4_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_ENET_PLL_DIV10,
|
|
IMX7CLK_SYS_PLL_PFD0, IMX7CLK_ENET_PLL_DIV25,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_REF_1M,
|
|
IMX7CLK_AUDIO_PLL, IMX7CLK_EXT_CLK4
|
|
}
|
|
},
|
|
[IMX7CLK_TRACE_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_TRACE_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_USB_PLL,
|
|
IMX7CLK_EXT_CLK2, IMX7CLK_EXT_CLK3
|
|
}
|
|
},
|
|
[IMX7CLK_WDOG_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_WDOG_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_USB_PLL,
|
|
IMX7CLK_REF_1M, IMX7CLK_SYS_PLL_PFD1_DIV2
|
|
}
|
|
},
|
|
[IMX7CLK_CSI_MCLK_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_CSI_MCLK_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_AUDIO_MCLK_CLK_ROOT] = {
|
|
.targetroot = CCM_CLKROOT_AUDIO_MCLK_CLK_ROOT,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_PFD2_DIV2,
|
|
IMX7CLK_SYS_PLL_DIV4, IMX7CLK_DDR_PLL_DIV2,
|
|
IMX7CLK_ENET_PLL_DIV8, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_USB_PLL
|
|
}
|
|
},
|
|
[IMX7CLK_CCM_CLKO1] = {
|
|
.targetroot = CCM_CLKROOT_CCM_CLKO1,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL,
|
|
IMX7CLK_SYS_PLL_DIV2, IMX7CLK_SYS_PLL_PFD0_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD3, IMX7CLK_ENET_PLL_DIV2,
|
|
IMX7CLK_DDR_PLL_DIV2, IMX7CLK_REF_1M
|
|
}
|
|
},
|
|
[IMX7CLK_CCM_CLKO2] = {
|
|
.targetroot = CCM_CLKROOT_CCM_CLKO2,
|
|
.type = CLKTYPE_IP,
|
|
.clksrc = {
|
|
IMX7CLK_OSC_24M, IMX7CLK_SYS_PLL_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD0, IMX7CLK_SYS_PLL_PFD1_DIV2,
|
|
IMX7CLK_SYS_PLL_PFD4, IMX7CLK_AUDIO_PLL,
|
|
IMX7CLK_VIDEO_PLL, IMX7CLK_OSC_32K
|
|
}
|
|
}
|
|
};
|
|
|
|
struct imxccm_softc *ccm_softc;
|
|
|
|
static int imxccm_match(device_t, cfdata_t, void *);
|
|
static void imxccm_attach(device_t, device_t, void *);
|
|
|
|
static int imxccm_sysctl_freq_helper(SYSCTLFN_PROTO);
|
|
static int imxccm_sysctl_setup(struct imxccm_softc *);
|
|
|
|
CFATTACH_DECL_NEW(imxccm, sizeof(struct imxccm_softc),
|
|
imxccm_match, imxccm_attach, NULL, NULL);
|
|
|
|
/* ARGSUSED */
|
|
static int
|
|
imxccm_match(device_t parent __unused, cfdata_t cfdata __unused, void *aux)
|
|
{
|
|
struct axi_attach_args *aa = aux;
|
|
|
|
if (ccm_softc != NULL)
|
|
return 0;
|
|
|
|
if (aa->aa_addr == IMX7_AIPS_BASE + AIPS1_CCM_BASE)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
static void
|
|
imxccm_attach(device_t parent __unused, device_t self, void *aux)
|
|
{
|
|
struct imxccm_softc * const sc = device_private(self);
|
|
struct axi_attach_args *aa = aux;
|
|
bus_space_tag_t iot = aa->aa_iot;
|
|
|
|
ccm_softc = sc;
|
|
sc->sc_dev = self;
|
|
sc->sc_iot = iot;
|
|
sc->sc_log = NULL;
|
|
|
|
if (bus_space_map(iot, IMX7_AIPS_BASE + AIPS1_CCM_BASE,
|
|
AIPS1_CCM_SIZE, 0, &sc->sc_ioh)) {
|
|
aprint_error(": can't map CCM registers\n");
|
|
return;
|
|
}
|
|
|
|
if (bus_space_map(iot, IMX7_AIPS_BASE + AIPS1_CCM_ANALOG_BASE,
|
|
AIPS1_CCM_ANALOG_SIZE, 0, &sc->sc_ioh_analog)) {
|
|
aprint_error(": can't map CCM_ANALOG registers\n");
|
|
bus_space_unmap(iot, sc->sc_ioh, AIPS1_CCM_SIZE);
|
|
return;
|
|
}
|
|
|
|
aprint_normal(": Clock Control Module\n");
|
|
aprint_naive("\n");
|
|
|
|
imxccm_sysctl_setup(sc);
|
|
|
|
aprint_verbose_dev(self, "ARM_PLL clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_ARM_PLL));
|
|
aprint_verbose_dev(self, "SYS_PLL clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_SYS_PLL));
|
|
aprint_verbose_dev(self, "ENET_PLL clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_ENET_PLL));
|
|
aprint_verbose_dev(self, "AUDIO_PLL clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_AUDIO_PLL));
|
|
aprint_verbose_dev(self, "VIDEO_PLL clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_VIDEO_PLL));
|
|
aprint_verbose_dev(self, "DDR_PLL clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_DDR_PLL));
|
|
aprint_verbose_dev(self, "USB_PLL clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_USB_PLL));
|
|
aprint_verbose_dev(self, "AXI clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_MAIN_AXI_CLK_ROOT));
|
|
aprint_verbose_dev(self, "ENET AXI clock=%d\n",
|
|
imx7_get_clock(IMX7CLK_ENET_AXI_CLK_ROOT));
|
|
|
|
#ifdef CCM_DEBUG
|
|
#define CLOCK_PRINT(name) \
|
|
printf(# name " clock=%d\n", imx7_get_clock(name))
|
|
|
|
CLOCK_PRINT(IMX7CLK_OSC_24M);
|
|
|
|
CLOCK_PRINT(IMX7CLK_ARM_PLL);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL);
|
|
CLOCK_PRINT(IMX7CLK_ENET_PLL);
|
|
CLOCK_PRINT(IMX7CLK_AUDIO_PLL);
|
|
CLOCK_PRINT(IMX7CLK_VIDEO_PLL);
|
|
CLOCK_PRINT(IMX7CLK_DDR_PLL);
|
|
CLOCK_PRINT(IMX7CLK_USB_PLL);
|
|
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD0);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD1);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD2);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD3);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD4);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD5);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD6);
|
|
CLOCK_PRINT(IMX7CLK_SYS_PLL_PFD7);
|
|
|
|
CLOCK_PRINT(IMX7CLK_ARM_A7_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_ARM_M4_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_MAIN_AXI_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_ENET_AXI_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_AHB_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_IPG_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_DRAM_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_DRAM_ALT_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_USB_HSIC_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_NAND_USDHC_BUS_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_USDHC1_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_USDHC2_CLK_ROOT);
|
|
CLOCK_PRINT(IMX7CLK_USDHC3_CLK_ROOT);
|
|
#endif
|
|
}
|
|
|
|
static int
|
|
imxccm_sysctl_setup(struct imxccm_softc *sc)
|
|
{
|
|
const struct sysctlnode *node, *imxnode, *freqnode, *pllnode;
|
|
int rv;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, NULL, &node,
|
|
CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
|
|
NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &node, &imxnode,
|
|
0, CTLTYPE_NODE, "imx7", NULL,
|
|
NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &imxnode, &freqnode,
|
|
0, CTLTYPE_NODE, "frequency", NULL,
|
|
NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &pllnode,
|
|
0, CTLTYPE_NODE, "pll", NULL,
|
|
NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
|
|
CTLFLAG_READWRITE, CTLTYPE_INT, "arm",
|
|
SYSCTL_DESCR("frequency of ARM clock (ARM_PLL)"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_arm_pll = node->sysctl_num;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
|
|
0, CTLTYPE_INT, "system",
|
|
SYSCTL_DESCR("frequency of system clock (SYS_PLL)"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_sys_pll = node->sysctl_num;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
|
|
0, CTLTYPE_INT, "enet",
|
|
SYSCTL_DESCR("frequency of enet clock (ENET_PLL)"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_enet_pll = node->sysctl_num;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
|
|
0, CTLTYPE_INT, "audio",
|
|
SYSCTL_DESCR("frequency of audio clock (AUDIO_PLL)"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_audio_pll = node->sysctl_num;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
|
|
0, CTLTYPE_INT, "video",
|
|
SYSCTL_DESCR("frequency of video clock (VIDEO_PLL)"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_video_pll = node->sysctl_num;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
|
|
0, CTLTYPE_INT, "ddr",
|
|
SYSCTL_DESCR("frequency of DDR clock (DDR_PLL)"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_ddr_pll = node->sysctl_num;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
|
|
0, CTLTYPE_INT, "usb",
|
|
SYSCTL_DESCR("frequency of USB clock (USB_PLL)"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_usb_pll = node->sysctl_num;
|
|
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
|
|
CTLFLAG_READWRITE, CTLTYPE_INT, "arm_a7",
|
|
SYSCTL_DESCR("frequency of ARM A7 Root clock"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_arm_a7_clk = node->sysctl_num;
|
|
|
|
rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
|
|
CTLFLAG_READWRITE, CTLTYPE_INT, "arm_m4",
|
|
SYSCTL_DESCR("frequency of ARM M4 Root clock"),
|
|
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
|
|
if (rv != 0)
|
|
goto fail;
|
|
sc->sc_sysctlnode_arm_m4_clk = node->sysctl_num;
|
|
|
|
|
|
return 0;
|
|
|
|
fail:
|
|
aprint_error_dev(sc->sc_dev, "cannot initialize sysctl (err=%d)\n", rv);
|
|
|
|
sysctl_teardown(&sc->sc_log);
|
|
sc->sc_log = NULL;
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int
|
|
imxccm_sysctl_freq_helper(SYSCTLFN_ARGS)
|
|
{
|
|
struct sysctlnode node;
|
|
struct imxccm_softc *sc;
|
|
int value, ovalue, err;
|
|
|
|
node = *rnode;
|
|
sc = node.sysctl_data;
|
|
|
|
/* for sysctl read */
|
|
if (rnode->sysctl_num == sc->sc_sysctlnode_arm_pll)
|
|
value = imx7_get_clock(IMX7CLK_ARM_PLL);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_sys_pll)
|
|
value = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_enet_pll)
|
|
value = imx7_get_clock(IMX7CLK_ENET_PLL);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_audio_pll)
|
|
value = imx7_get_clock(IMX7CLK_AUDIO_PLL);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_video_pll)
|
|
value = imx7_get_clock(IMX7CLK_VIDEO_PLL);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_ddr_pll)
|
|
value = imx7_get_clock(IMX7CLK_DDR_PLL);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_usb_pll)
|
|
value = imx7_get_clock(IMX7CLK_USB_PLL);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_arm_a7_clk)
|
|
value = imx7_get_clock(IMX7CLK_ARM_A7_CLK_ROOT);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_arm_m4_clk)
|
|
value = imx7_get_clock(IMX7CLK_ARM_M4_CLK_ROOT);
|
|
else
|
|
return EOPNOTSUPP;
|
|
|
|
#ifdef SYSCTL_BY_MHZ
|
|
value /= 1000 * 1000; /* Hz -> MHz */
|
|
#endif
|
|
ovalue = value;
|
|
|
|
node.sysctl_data = &value;
|
|
err = sysctl_lookup(SYSCTLFN_CALL(&node));
|
|
if (err != 0 || newp == NULL)
|
|
return err;
|
|
|
|
/* for sysctl write */
|
|
if (value == ovalue)
|
|
return 0;
|
|
|
|
#ifdef SYSCTL_BY_MHZ
|
|
value *= 1000 * 1000; /* MHz -> Hz */
|
|
#endif
|
|
|
|
if (rnode->sysctl_num == sc->sc_sysctlnode_arm_pll)
|
|
return imx7_set_clock(IMX7CLK_ARM_PLL, value);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_arm_a7_clk)
|
|
return imx7_set_clock(IMX7CLK_ARM_A7_CLK_ROOT, value);
|
|
else if (rnode->sysctl_num == sc->sc_sysctlnode_arm_m4_clk)
|
|
return imx7_set_clock(IMX7CLK_ARM_M4_CLK_ROOT, value);
|
|
|
|
return EOPNOTSUPP;
|
|
}
|
|
|
|
|
|
uint32_t
|
|
imx7_ccm_read(uint32_t reg)
|
|
{
|
|
if (ccm_softc == NULL)
|
|
return 0;
|
|
|
|
return bus_space_read_4(ccm_softc->sc_iot, ccm_softc->sc_ioh, reg);
|
|
}
|
|
|
|
void
|
|
imx7_ccm_write(uint32_t reg, uint32_t val)
|
|
{
|
|
if (ccm_softc == NULL)
|
|
return;
|
|
|
|
bus_space_write_4(ccm_softc->sc_iot, ccm_softc->sc_ioh, reg, val);
|
|
}
|
|
|
|
uint32_t
|
|
imx7_ccm_analog_read(uint32_t reg)
|
|
{
|
|
if (ccm_softc == NULL)
|
|
return 0;
|
|
|
|
return bus_space_read_4(ccm_softc->sc_iot, ccm_softc->sc_ioh_analog,
|
|
reg);
|
|
}
|
|
|
|
void
|
|
imx7_ccm_analog_write(uint32_t reg, uint32_t val)
|
|
{
|
|
if (ccm_softc == NULL)
|
|
return;
|
|
|
|
bus_space_write_4(ccm_softc->sc_iot, ccm_softc->sc_ioh_analog, reg,
|
|
val);
|
|
}
|
|
|
|
static uint64_t
|
|
rootclk(int clk, bool nodiv)
|
|
{
|
|
uint32_t d, v;
|
|
uint64_t freq;
|
|
|
|
/* read CCM_TARGET_ROOTxx */
|
|
v = imx7_ccm_read(imx7clkroottbl[clk].targetroot);
|
|
|
|
if ((v & CCM_TARGET_ROOT_ENABLE) == 0)
|
|
return 0;
|
|
|
|
d = __SHIFTOUT(v, CCM_TARGET_ROOT_MUX);
|
|
freq = imx7_get_clock(imx7clkroottbl[clk].clksrc[d]);
|
|
|
|
#ifdef CCM_DEBUG
|
|
if (ccm_debug) {
|
|
printf("TARGET_ROOT[%08x]: value=%08x, mux=%d, freq=%llu\n",
|
|
imx7clkroottbl[clk].targetroot, v, d, freq);
|
|
}
|
|
#endif
|
|
|
|
if (nodiv)
|
|
return freq;
|
|
|
|
/* eval TARGET_ROOT[PRE_PODF] */
|
|
if ((imx7clkroottbl[clk].type != CLKTYPE_CORE) &&
|
|
(imx7clkroottbl[clk].type != CLKTYPE_DRAM) &&
|
|
(imx7clkroottbl[clk].type != CLKTYPE_DRAM_PHYM)) {
|
|
d = __SHIFTOUT(v, CCM_TARGET_ROOT_PRE_PODF) + 1;
|
|
freq /= d;
|
|
#ifdef CCM_DEBUG
|
|
if (ccm_debug) {
|
|
printf("TARGET_ROOT[%08x]: pre_podf=%d, freq=%llu\n",
|
|
imx7clkroottbl[clk].targetroot, d, freq);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* eval TARGET_ROOT[POST_PODF] */
|
|
if (clk != IMX7CLK_DRAM_PHYM_CLK_ROOT) {
|
|
d = __SHIFTOUT(v, CCM_TARGET_ROOT_POST_PODF) + 1;
|
|
if (clk == IMX7CLK_DRAM_CLK_ROOT)
|
|
d &= 7;
|
|
freq /= d;
|
|
#ifdef CCM_DEBUG
|
|
if (ccm_debug) {
|
|
printf("TARGET_ROOT[%08x]: post_podf=%d, freq=%llu\n",
|
|
imx7clkroottbl[clk].targetroot, d, freq);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* eval TARGET_ROOT[AUTO_PODF] (from u-boot source, not datasheet) */
|
|
if ((imx7clkroottbl[clk].type != CLKTYPE_AHB) &&
|
|
(imx7clkroottbl[clk].type != CLKTYPE_BUS)) {
|
|
if (v & CCM_TARGET_ROOT_AUTO_ENABLE) {
|
|
d = __SHIFTOUT(v, CCM_TARGET_ROOT_AUTO_PODF) + 1;
|
|
freq /= d;
|
|
#ifdef CCM_DEBUG
|
|
if (ccm_debug) {
|
|
printf("TARGET_ROOT[%08x]: "
|
|
"auto_podf=%d, freq=%llu\n",
|
|
imx7clkroottbl[clk].targetroot, d, freq);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return freq;
|
|
}
|
|
|
|
/* see also iMX7 Reference Manual 5.2.6.1 Input Clocks */
|
|
uint32_t
|
|
imx7_get_clock(enum imx7_clock clk)
|
|
{
|
|
uint32_t d, denom, num, v;
|
|
uint64_t freq = 0;
|
|
|
|
if (ccm_softc == NULL)
|
|
return 0;
|
|
|
|
switch (clk) {
|
|
case IMX7CLK_OSC_24M:
|
|
freq = IMX7_OSC_FREQ; /* fixed clock */
|
|
break;
|
|
case IMX7CLK_REF_1M:
|
|
freq = IMX7_OSC_FREQ / 24; /* fixed clock */
|
|
break;
|
|
case IMX7CLK_OSC_32K:
|
|
freq = IMX7_OSC_FREQ / 768; /* fixed clock */
|
|
break;
|
|
|
|
case IMX7CLK_ARM_PLL:
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PLL_ARM);
|
|
freq = IMX7_OSC_FREQ *
|
|
__SHIFTOUT(v, CCM_ANALOG_PLL_ARM_DIV_SELECT) / 2;
|
|
break;
|
|
|
|
case IMX7CLK_DDR_PLL:
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PLL_DDR);
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_DDR_DIV_SELECT);
|
|
num = imx7_ccm_analog_read(CCM_ANALOG_PLL_DDR_NUM);
|
|
denom = imx7_ccm_analog_read(CCM_ANALOG_PLL_DDR_DENOM);
|
|
freq = (uint64_t)IMX7_OSC_FREQ * (d + num / denom);
|
|
if (v & CCM_ANALOG_PLL_DDR_DIV2_ENABLE_CLK)
|
|
freq /= 2;
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_DDR_TEST_DIV_SELECT);
|
|
switch (d) {
|
|
case 0:
|
|
freq /= 4;
|
|
break;
|
|
case 1:
|
|
freq /= 2;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
break;
|
|
}
|
|
break;
|
|
case IMX7CLK_DDR_PLL_DIV2:
|
|
freq = imx7_get_clock(IMX7CLK_DDR_PLL) / 2;
|
|
break;
|
|
|
|
case IMX7CLK_SYS_PLL:
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PLL_480);
|
|
freq = IMX7_OSC_FREQ *
|
|
((v & CCM_ANALOG_PLL_480_DIV_SELECT) ? 22 : 20);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_DIV2:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL) / 2;
|
|
break;
|
|
case IMX7CLK_SYS_PLL_DIV4:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL) / 4;
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD0:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480A);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480A_PDF0_FRAC);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD0_DIV2:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL_PFD0) / 2;
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD1:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480A);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480A_PDF1_FRAC);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD1_DIV2:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL_PFD1) / 2;
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD2:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480A);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480A_PDF2_FRAC);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD2_DIV2:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL_PFD2) / 2;
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD3:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480A);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480A_PDF3_FRAC);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD4:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480B);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480B_PDF4_FRAC);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD5:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480B);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480B_PDF5_FRAC);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD6:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480B);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480B_PDF6_FRAC);
|
|
break;
|
|
case IMX7CLK_SYS_PLL_PFD7:
|
|
freq = imx7_get_clock(IMX7CLK_SYS_PLL);
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PFD_480B);
|
|
freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480B_PDF7_FRAC);
|
|
break;
|
|
|
|
case IMX7CLK_ENET_PLL:
|
|
freq = IMX7_ENET_PLL_CLK; /* fixed clock */
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV2:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 2;
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV4:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 4;
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV8:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 8;
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV10:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 10;
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV20:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 20;
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV25:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 25;
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV40:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 40;
|
|
break;
|
|
case IMX7CLK_ENET_PLL_DIV50:
|
|
freq = imx7_get_clock(IMX7CLK_ENET_PLL) / 50;
|
|
break;
|
|
|
|
case IMX7CLK_USB_PLL:
|
|
freq = IMX7_USB_PLL_CLK; /* fixed clock */
|
|
break;
|
|
case IMX7CLK_AUDIO_PLL:
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PLL_AUDIO);
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_AUDIO_DIV_SELECT);
|
|
num = imx7_ccm_analog_read(CCM_ANALOG_PLL_AUDIO_NUM);
|
|
denom = imx7_ccm_analog_read(CCM_ANALOG_PLL_AUDIO_DENOM);
|
|
freq = (uint64_t)IMX7_OSC_FREQ * (d + num / denom);
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_AUDIO_TEST_DIV_SELECT);
|
|
switch (d) {
|
|
case 0:
|
|
freq /= 4;
|
|
break;
|
|
case 1:
|
|
freq /= 2;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
break;
|
|
}
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT);
|
|
switch (d) {
|
|
case 0:
|
|
case 2:
|
|
break;
|
|
case 1:
|
|
freq /= 2;
|
|
break;
|
|
case 3:
|
|
freq /= 4;
|
|
break;
|
|
}
|
|
break;
|
|
case IMX7CLK_VIDEO_PLL:
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PLL_VIDEO);
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_VIDEO_DIV_SELECT);
|
|
num = imx7_ccm_analog_read(CCM_ANALOG_PLL_VIDEO_NUM);
|
|
denom = imx7_ccm_analog_read(CCM_ANALOG_PLL_VIDEO_DENOM);
|
|
freq = (uint64_t)IMX7_OSC_FREQ * (d + num / denom);
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_VIDEO_TEST_DIV_SELECT);
|
|
switch (d) {
|
|
case 0:
|
|
freq /= 4;
|
|
break;
|
|
case 1:
|
|
freq /= 2;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
break;
|
|
}
|
|
d = __SHIFTOUT(v, CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT);
|
|
switch (d) {
|
|
case 0:
|
|
case 2:
|
|
break;
|
|
case 1:
|
|
freq /= 2;
|
|
break;
|
|
case 3:
|
|
freq /= 4;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case IMX7CLK_ARM_A7_CLK_ROOT:
|
|
case IMX7CLK_ARM_M4_CLK_ROOT:
|
|
case IMX7CLK_MAIN_AXI_CLK_ROOT:
|
|
case IMX7CLK_DISP_AXI_CLK_ROOT:
|
|
case IMX7CLK_ENET_AXI_CLK_ROOT:
|
|
case IMX7CLK_NAND_USDHC_BUS_CLK_ROOT:
|
|
case IMX7CLK_AHB_CLK_ROOT:
|
|
case IMX7CLK_IPG_CLK_ROOT:
|
|
case IMX7CLK_DRAM_PHYM_CLK_ROOT:
|
|
case IMX7CLK_DRAM_CLK_ROOT:
|
|
case IMX7CLK_DRAM_PHYM_ALT_CLK_ROOT:
|
|
case IMX7CLK_DRAM_ALT_CLK_ROOT:
|
|
case IMX7CLK_USB_HSIC_CLK_ROOT:
|
|
case IMX7CLK_PCIE_CTRL_CLK_ROOT:
|
|
case IMX7CLK_PCIE_PHY_CLK_ROOT:
|
|
case IMX7CLK_EPDC_PIXEL_CLK_ROOT:
|
|
case IMX7CLK_LCDIF_PIXEL_CLK_ROOT:
|
|
case IMX7CLK_MIPI_DSI_CLK_ROOT:
|
|
case IMX7CLK_MIPI_CSI_CLK_ROOT:
|
|
case IMX7CLK_MIPI_DPHY_REF_CLK_ROOT:
|
|
case IMX7CLK_SAI1_CLK_ROOT:
|
|
case IMX7CLK_SAI2_CLK_ROOT:
|
|
case IMX7CLK_SAI3_CLK_ROOT:
|
|
case IMX7CLK_ENET1_REF_CLK_ROOT:
|
|
case IMX7CLK_ENET1_TIME_CLK_ROOT:
|
|
case IMX7CLK_ENET2_REF_CLK_ROOT:
|
|
case IMX7CLK_ENET2_TIME_CLK_ROOT:
|
|
case IMX7CLK_ENET_PHY_REF_CLK_ROOT:
|
|
case IMX7CLK_EIM_CLK_ROOT:
|
|
case IMX7CLK_NAND_CLK_ROOT:
|
|
case IMX7CLK_QSPI_CLK_ROOT:
|
|
case IMX7CLK_USDHC1_CLK_ROOT:
|
|
case IMX7CLK_USDHC2_CLK_ROOT:
|
|
case IMX7CLK_USDHC3_CLK_ROOT:
|
|
case IMX7CLK_CAN1_CLK_ROOT:
|
|
case IMX7CLK_CAN2_CLK_ROOT:
|
|
case IMX7CLK_I2C1_CLK_ROOT:
|
|
case IMX7CLK_I2C2_CLK_ROOT:
|
|
case IMX7CLK_I2C3_CLK_ROOT:
|
|
case IMX7CLK_I2C4_CLK_ROOT:
|
|
case IMX7CLK_UART1_CLK_ROOT:
|
|
case IMX7CLK_UART2_CLK_ROOT:
|
|
case IMX7CLK_UART3_CLK_ROOT:
|
|
case IMX7CLK_UART4_CLK_ROOT:
|
|
case IMX7CLK_UART5_CLK_ROOT:
|
|
case IMX7CLK_UART6_CLK_ROOT:
|
|
case IMX7CLK_UART7_CLK_ROOT:
|
|
case IMX7CLK_ECSPI1_CLK_ROOT:
|
|
case IMX7CLK_ECSPI2_CLK_ROOT:
|
|
case IMX7CLK_ECSPI3_CLK_ROOT:
|
|
case IMX7CLK_ECSPI4_CLK_ROOT:
|
|
case IMX7CLK_PWM1_CLK_ROOT:
|
|
case IMX7CLK_PWM2_CLK_ROOT:
|
|
case IMX7CLK_PWM3_CLK_ROOT:
|
|
case IMX7CLK_PWM4_CLK_ROOT:
|
|
case IMX7CLK_FLEXTIMER1_CLK_ROOT:
|
|
case IMX7CLK_FLEXTIMER2_CLK_ROOT:
|
|
case IMX7CLK_SIM1_CLK_ROOT:
|
|
case IMX7CLK_SIM2_CLK_ROOT:
|
|
case IMX7CLK_GPT1_CLK_ROOT:
|
|
case IMX7CLK_GPT2_CLK_ROOT:
|
|
case IMX7CLK_GPT3_CLK_ROOT:
|
|
case IMX7CLK_GPT4_CLK_ROOT:
|
|
case IMX7CLK_TRACE_CLK_ROOT:
|
|
case IMX7CLK_WDOG_CLK_ROOT:
|
|
case IMX7CLK_CSI_MCLK_CLK_ROOT:
|
|
case IMX7CLK_AUDIO_MCLK_CLK_ROOT:
|
|
case IMX7CLK_CCM_CLKO1:
|
|
case IMX7CLK_CCM_CLKO2:
|
|
freq = rootclk(clk, false);
|
|
break;
|
|
|
|
default:
|
|
aprint_error_dev(ccm_softc->sc_dev,
|
|
"%s: clockid %d: not supported\n", __func__, clk);
|
|
return 0;
|
|
}
|
|
|
|
return freq;
|
|
}
|
|
|
|
/*
|
|
* resolve two clock divisors d3 and d6.
|
|
* freq = maxfreq / d3(3bit) / d6(6bit)
|
|
*/
|
|
static void
|
|
getrootclkdiv(uint32_t maxfreq, uint32_t freq, uint32_t *d3p, uint32_t *d6p)
|
|
{
|
|
uint32_t c_dif, c_d3, c_d6;
|
|
uint32_t dif, d3, d6;
|
|
uint32_t lim, base, f;
|
|
|
|
c_dif = 0xffffffff;
|
|
c_d3 = c_d6 = 0;
|
|
for (d3 = 0; d3 < 8; d3++) {
|
|
base = 0;
|
|
for (lim = 64; lim != 0; lim >>= 1) {
|
|
d6 = (lim >> 1) + base;
|
|
f = maxfreq / (d3 + 1) / (d6 + 1);
|
|
if (freq < f) {
|
|
base = d6 + 1;
|
|
lim--;
|
|
}
|
|
dif = (freq > f) ? freq - f : f - freq;
|
|
if (c_dif > dif) {
|
|
c_dif = dif;
|
|
c_d3 = d3;
|
|
c_d6 = d6;
|
|
}
|
|
}
|
|
}
|
|
*d3p = c_d3;
|
|
*d6p = c_d6;
|
|
}
|
|
|
|
int
|
|
imx7_set_clock(enum imx7_clock clk, uint32_t freq)
|
|
{
|
|
uint32_t v, x;
|
|
uint32_t d3, d6, maxfreq;
|
|
|
|
if (ccm_softc == NULL)
|
|
return 0;
|
|
|
|
switch (clk) {
|
|
case IMX7CLK_ARM_PLL:
|
|
x = (uint64_t)freq * 2 / IMX7_OSC_FREQ;
|
|
v = imx7_ccm_analog_read(CCM_ANALOG_PLL_ARM);
|
|
v &= ~CCM_ANALOG_PLL_ARM_DIV_SELECT;
|
|
v |= __SHIFTIN(x, CCM_ANALOG_PLL_ARM_DIV_SELECT);
|
|
imx7_ccm_analog_write(CCM_ANALOG_PLL_ARM, v);
|
|
break;
|
|
|
|
/* core type clock */
|
|
case IMX7CLK_ARM_A7_CLK_ROOT:
|
|
maxfreq = rootclk(clk, true);
|
|
getrootclkdiv(maxfreq, freq, &d3, &d6);
|
|
v = imx7_ccm_read(imx7clkroottbl[clk].targetroot);
|
|
/* core type clocks use AUTO_PODF and POST_PODF */
|
|
v &= ~CCM_TARGET_ROOT_AUTO_PODF;
|
|
v |= __SHIFTIN(d3, CCM_TARGET_ROOT_AUTO_PODF);
|
|
v |= CCM_TARGET_ROOT_AUTO_ENABLE;
|
|
v &= ~CCM_TARGET_ROOT_POST_PODF;
|
|
v |= __SHIFTIN(d6, CCM_TARGET_ROOT_POST_PODF);
|
|
imx7_ccm_write(imx7clkroottbl[clk].targetroot, v);
|
|
break;
|
|
|
|
/* bus type clocks */
|
|
case IMX7CLK_ARM_M4_CLK_ROOT:
|
|
case IMX7CLK_MAIN_AXI_CLK_ROOT:
|
|
case IMX7CLK_DISP_AXI_CLK_ROOT:
|
|
maxfreq = rootclk(clk, true);
|
|
getrootclkdiv(maxfreq, freq, &d3, &d6);
|
|
/* bus type clocks use PRE_PODF and POST_PODF */
|
|
v = imx7_ccm_read(imx7clkroottbl[clk].targetroot);
|
|
v &= ~CCM_TARGET_ROOT_PRE_PODF;
|
|
v |= __SHIFTIN(d3, CCM_TARGET_ROOT_PRE_PODF);
|
|
v &= ~CCM_TARGET_ROOT_POST_PODF;
|
|
v |= __SHIFTIN(d6, CCM_TARGET_ROOT_POST_PODF);
|
|
imx7_ccm_write(imx7clkroottbl[clk].targetroot, v);
|
|
break;
|
|
|
|
default:
|
|
aprint_error_dev(ccm_softc->sc_dev,
|
|
"%s: clockid %d: not supported\n", __func__, clk);
|
|
return EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
imx7_pll_power(uint32_t pllreg, int on)
|
|
{
|
|
uint32_t v;
|
|
int timeout;
|
|
|
|
switch (pllreg) {
|
|
case CCM_ANALOG_PLL_ENET:
|
|
v = imx7_ccm_analog_read(pllreg);
|
|
if (on)
|
|
v &= ~CCM_ANALOG_PLL_ENET_POWERDOWN;
|
|
else
|
|
v |= CCM_ANALOG_PLL_ENET_POWERDOWN;
|
|
imx7_ccm_analog_write(pllreg, v);
|
|
|
|
for (timeout = 100000; timeout > 0; timeout--) {
|
|
if (imx7_ccm_analog_read(pllreg) &
|
|
CCM_ANALOG_PLL_ENET_LOCK)
|
|
break;
|
|
}
|
|
if (timeout <= 0)
|
|
break;
|
|
|
|
if (on) {
|
|
v &= ~CCM_ANALOG_PLL_ENET_BYPASS;
|
|
v |= CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ;
|
|
v |= CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ;
|
|
v |= CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ;
|
|
v |= CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ;
|
|
v |= CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ;
|
|
v |= CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ;
|
|
v |= CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ;
|
|
} else {
|
|
v &= ~CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ;
|
|
v &= ~CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ;
|
|
v &= ~CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ;
|
|
v &= ~CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ;
|
|
v &= ~CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ;
|
|
v &= ~CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ;
|
|
v &= ~CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ;
|
|
}
|
|
imx7_ccm_analog_write(pllreg, v);
|
|
return 0;
|
|
|
|
case CCM_ANALOG_PLL_ARM:
|
|
case CCM_ANALOG_PLL_DDR:
|
|
case CCM_ANALOG_PLL_480:
|
|
case CCM_ANALOG_PLL_AUDIO:
|
|
case CCM_ANALOG_PLL_VIDEO:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return -1;
|
|
}
|