2018-12-13 18:42:58 +03:00
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
* Dong Aisheng < aisheng . dong @ nxp . com >
*/
# include <linux/clk-provider.h>
# include <linux/err.h>
# include <linux/io.h>
# include <linux/module.h>
# include <linux/of.h>
# include <linux/platform_device.h>
# include <linux/slab.h>
# include "clk-scu.h"
2018-12-23 19:20:02 +03:00
# include <dt-bindings/clock/imx8-clock.h>
2018-12-13 18:42:58 +03:00
# include <dt-bindings/firmware/imx/rsrc.h>
static int imx8qxp_clk_probe ( struct platform_device * pdev )
{
struct device_node * ccm_node = pdev - > dev . of_node ;
struct clk_hw_onecell_data * clk_data ;
struct clk_hw * * clks ;
int ret , i ;
ret = imx_clk_scu_init ( ) ;
if ( ret )
return ret ;
clk_data = devm_kzalloc ( & pdev - > dev , struct_size ( clk_data , hws ,
2018-12-23 19:20:02 +03:00
IMX_SCU_CLK_END ) , GFP_KERNEL ) ;
2018-12-13 18:42:58 +03:00
if ( ! clk_data )
return - ENOMEM ;
2018-12-23 19:20:02 +03:00
clk_data - > num = IMX_SCU_CLK_END ;
2018-12-13 18:42:58 +03:00
clks = clk_data - > hws ;
/* Fixed clocks */
2018-12-23 19:20:02 +03:00
clks [ IMX_CLK_DUMMY ] = clk_hw_register_fixed_rate ( NULL , " dummy " , NULL , 0 , 0 ) ;
clks [ IMX_ADMA_IPG_CLK_ROOT ] = clk_hw_register_fixed_rate ( NULL , " dma_ipg_clk_root " , NULL , 0 , 120000000 ) ;
clks [ IMX_CONN_AXI_CLK_ROOT ] = clk_hw_register_fixed_rate ( NULL , " conn_axi_clk_root " , NULL , 0 , 333333333 ) ;
clks [ IMX_CONN_AHB_CLK_ROOT ] = clk_hw_register_fixed_rate ( NULL , " conn_ahb_clk_root " , NULL , 0 , 166666666 ) ;
clks [ IMX_CONN_IPG_CLK_ROOT ] = clk_hw_register_fixed_rate ( NULL , " conn_ipg_clk_root " , NULL , 0 , 83333333 ) ;
clks [ IMX_DC_AXI_EXT_CLK ] = clk_hw_register_fixed_rate ( NULL , " dc_axi_ext_clk_root " , NULL , 0 , 800000000 ) ;
clks [ IMX_DC_AXI_INT_CLK ] = clk_hw_register_fixed_rate ( NULL , " dc_axi_int_clk_root " , NULL , 0 , 400000000 ) ;
clks [ IMX_DC_CFG_CLK ] = clk_hw_register_fixed_rate ( NULL , " dc_cfg_clk_root " , NULL , 0 , 100000000 ) ;
clks [ IMX_MIPI_IPG_CLK ] = clk_hw_register_fixed_rate ( NULL , " mipi_ipg_clk_root " , NULL , 0 , 120000000 ) ;
clks [ IMX_IMG_AXI_CLK ] = clk_hw_register_fixed_rate ( NULL , " img_axi_clk_root " , NULL , 0 , 400000000 ) ;
clks [ IMX_IMG_IPG_CLK ] = clk_hw_register_fixed_rate ( NULL , " img_ipg_clk_root " , NULL , 0 , 200000000 ) ;
clks [ IMX_IMG_PXL_CLK ] = clk_hw_register_fixed_rate ( NULL , " img_pxl_clk_root " , NULL , 0 , 600000000 ) ;
clks [ IMX_HSIO_AXI_CLK ] = clk_hw_register_fixed_rate ( NULL , " hsio_axi_clk_root " , NULL , 0 , 400000000 ) ;
clks [ IMX_HSIO_PER_CLK ] = clk_hw_register_fixed_rate ( NULL , " hsio_per_clk_root " , NULL , 0 , 133333333 ) ;
clks [ IMX_LSIO_MEM_CLK ] = clk_hw_register_fixed_rate ( NULL , " lsio_mem_clk_root " , NULL , 0 , 200000000 ) ;
clks [ IMX_LSIO_BUS_CLK ] = clk_hw_register_fixed_rate ( NULL , " lsio_bus_clk_root " , NULL , 0 , 100000000 ) ;
2018-12-13 18:42:58 +03:00
/* ARM core */
2018-12-23 19:20:02 +03:00
clks [ IMX_A35_CLK ] = imx_clk_scu ( " a35_clk " , IMX_SC_R_A35 , IMX_SC_PM_CLK_CPU ) ;
2018-12-13 18:42:58 +03:00
/* LSIO SS */
2018-12-23 19:20:02 +03:00
clks [ IMX_LSIO_PWM0_CLK ] = imx_clk_scu ( " pwm0_clk " , IMX_SC_R_PWM_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_PWM1_CLK ] = imx_clk_scu ( " pwm1_clk " , IMX_SC_R_PWM_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_PWM2_CLK ] = imx_clk_scu ( " pwm2_clk " , IMX_SC_R_PWM_2 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_PWM3_CLK ] = imx_clk_scu ( " pwm3_clk " , IMX_SC_R_PWM_3 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_PWM4_CLK ] = imx_clk_scu ( " pwm4_clk " , IMX_SC_R_PWM_4 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_PWM5_CLK ] = imx_clk_scu ( " pwm5_clk " , IMX_SC_R_PWM_5 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_PWM6_CLK ] = imx_clk_scu ( " pwm6_clk " , IMX_SC_R_PWM_6 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_PWM7_CLK ] = imx_clk_scu ( " pwm7_clk " , IMX_SC_R_PWM_7 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_GPT0_CLK ] = imx_clk_scu ( " gpt0_clk " , IMX_SC_R_GPT_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_GPT1_CLK ] = imx_clk_scu ( " gpt1_clk " , IMX_SC_R_GPT_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_GPT2_CLK ] = imx_clk_scu ( " gpt2_clk " , IMX_SC_R_GPT_2 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_GPT3_CLK ] = imx_clk_scu ( " gpt3_clk " , IMX_SC_R_GPT_3 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_GPT4_CLK ] = imx_clk_scu ( " gpt4_clk " , IMX_SC_R_GPT_4 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_FSPI0_CLK ] = imx_clk_scu ( " fspi0_clk " , IMX_SC_R_FSPI_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_LSIO_FSPI1_CLK ] = imx_clk_scu ( " fspi1_clk " , IMX_SC_R_FSPI_1 , IMX_SC_PM_CLK_PER ) ;
2018-12-13 18:42:58 +03:00
/* ADMA SS */
2018-12-23 19:20:02 +03:00
clks [ IMX_ADMA_UART0_CLK ] = imx_clk_scu ( " uart0_clk " , IMX_SC_R_UART_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_UART1_CLK ] = imx_clk_scu ( " uart1_clk " , IMX_SC_R_UART_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_UART2_CLK ] = imx_clk_scu ( " uart2_clk " , IMX_SC_R_UART_2 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_UART3_CLK ] = imx_clk_scu ( " uart3_clk " , IMX_SC_R_UART_3 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_SPI0_CLK ] = imx_clk_scu ( " spi0_clk " , IMX_SC_R_SPI_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_SPI1_CLK ] = imx_clk_scu ( " spi1_clk " , IMX_SC_R_SPI_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_SPI2_CLK ] = imx_clk_scu ( " spi2_clk " , IMX_SC_R_SPI_2 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_SPI3_CLK ] = imx_clk_scu ( " spi3_clk " , IMX_SC_R_SPI_3 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_CAN0_CLK ] = imx_clk_scu ( " can0_clk " , IMX_SC_R_CAN_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_I2C0_CLK ] = imx_clk_scu ( " i2c0_clk " , IMX_SC_R_I2C_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_I2C1_CLK ] = imx_clk_scu ( " i2c1_clk " , IMX_SC_R_I2C_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_I2C2_CLK ] = imx_clk_scu ( " i2c2_clk " , IMX_SC_R_I2C_2 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_I2C3_CLK ] = imx_clk_scu ( " i2c3_clk " , IMX_SC_R_I2C_3 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_FTM0_CLK ] = imx_clk_scu ( " ftm0_clk " , IMX_SC_R_FTM_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_FTM1_CLK ] = imx_clk_scu ( " ftm1_clk " , IMX_SC_R_FTM_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_ADC0_CLK ] = imx_clk_scu ( " adc0_clk " , IMX_SC_R_ADC_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_PWM_CLK ] = imx_clk_scu ( " pwm_clk " , IMX_SC_R_LCD_0_PWM_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_ADMA_LCD_CLK ] = imx_clk_scu ( " lcd_clk " , IMX_SC_R_LCD_0 , IMX_SC_PM_CLK_PER ) ;
2018-12-13 18:42:58 +03:00
/* Connectivity */
2018-12-23 19:20:02 +03:00
clks [ IMX_CONN_SDHC0_CLK ] = imx_clk_scu ( " sdhc0_clk " , IMX_SC_R_SDHC_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CONN_SDHC1_CLK ] = imx_clk_scu ( " sdhc1_clk " , IMX_SC_R_SDHC_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CONN_SDHC2_CLK ] = imx_clk_scu ( " sdhc2_clk " , IMX_SC_R_SDHC_2 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CONN_ENET0_ROOT_CLK ] = imx_clk_scu ( " enet0_clk " , IMX_SC_R_ENET_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CONN_ENET0_BYPASS_CLK ] = imx_clk_scu ( " enet0_bypass_clk " , IMX_SC_R_ENET_0 , IMX_SC_PM_CLK_BYPASS ) ;
clks [ IMX_CONN_ENET0_RGMII_CLK ] = imx_clk_scu ( " enet0_rgmii_clk " , IMX_SC_R_ENET_0 , IMX_SC_PM_CLK_MISC0 ) ;
clks [ IMX_CONN_ENET1_ROOT_CLK ] = imx_clk_scu ( " enet1_clk " , IMX_SC_R_ENET_1 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CONN_ENET1_BYPASS_CLK ] = imx_clk_scu ( " enet1_bypass_clk " , IMX_SC_R_ENET_1 , IMX_SC_PM_CLK_BYPASS ) ;
clks [ IMX_CONN_ENET1_RGMII_CLK ] = imx_clk_scu ( " enet1_rgmii_clk " , IMX_SC_R_ENET_1 , IMX_SC_PM_CLK_MISC0 ) ;
clks [ IMX_CONN_GPMI_BCH_IO_CLK ] = imx_clk_scu ( " gpmi_io_clk " , IMX_SC_R_NAND , IMX_SC_PM_CLK_MST_BUS ) ;
clks [ IMX_CONN_GPMI_BCH_CLK ] = imx_clk_scu ( " gpmi_bch_clk " , IMX_SC_R_NAND , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CONN_USB2_ACLK ] = imx_clk_scu ( " usb3_aclk_div " , IMX_SC_R_USB_2 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CONN_USB2_BUS_CLK ] = imx_clk_scu ( " usb3_bus_div " , IMX_SC_R_USB_2 , IMX_SC_PM_CLK_MST_BUS ) ;
clks [ IMX_CONN_USB2_LPM_CLK ] = imx_clk_scu ( " usb3_lpm_div " , IMX_SC_R_USB_2 , IMX_SC_PM_CLK_MISC ) ;
2018-12-13 18:42:58 +03:00
/* Display controller SS */
2018-12-23 19:20:02 +03:00
clks [ IMX_DC0_DISP0_CLK ] = imx_clk_scu ( " dc0_disp0_clk " , IMX_SC_R_DC_0 , IMX_SC_PM_CLK_MISC0 ) ;
clks [ IMX_DC0_DISP1_CLK ] = imx_clk_scu ( " dc0_disp1_clk " , IMX_SC_R_DC_0 , IMX_SC_PM_CLK_MISC1 ) ;
2018-12-13 18:42:58 +03:00
/* MIPI-LVDS SS */
2018-12-23 19:20:02 +03:00
clks [ IMX_MIPI0_I2C0_CLK ] = imx_clk_scu ( " mipi0_i2c0_clk " , IMX_SC_R_MIPI_0_I2C_0 , IMX_SC_PM_CLK_MISC2 ) ;
clks [ IMX_MIPI0_I2C1_CLK ] = imx_clk_scu ( " mipi0_i2c1_clk " , IMX_SC_R_MIPI_0_I2C_1 , IMX_SC_PM_CLK_MISC2 ) ;
2018-12-13 18:42:58 +03:00
/* MIPI CSI SS */
2018-12-23 19:20:02 +03:00
clks [ IMX_CSI0_CORE_CLK ] = imx_clk_scu ( " mipi_csi0_core_clk " , IMX_SC_R_CSI_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CSI0_ESC_CLK ] = imx_clk_scu ( " mipi_csi0_esc_clk " , IMX_SC_R_CSI_0 , IMX_SC_PM_CLK_MISC ) ;
clks [ IMX_CSI0_I2C0_CLK ] = imx_clk_scu ( " mipi_csi0_i2c0_clk " , IMX_SC_R_CSI_0_I2C_0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_CSI0_PWM0_CLK ] = imx_clk_scu ( " mipi_csi0_pwm0_clk " , IMX_SC_R_CSI_0_PWM_0 , IMX_SC_PM_CLK_PER ) ;
2018-12-13 18:42:58 +03:00
/* GPU SS */
2018-12-23 19:20:02 +03:00
clks [ IMX_GPU0_CORE_CLK ] = imx_clk_scu ( " gpu_core0_clk " , IMX_SC_R_GPU_0_PID0 , IMX_SC_PM_CLK_PER ) ;
clks [ IMX_GPU0_SHADER_CLK ] = imx_clk_scu ( " gpu_shader0_clk " , IMX_SC_R_GPU_0_PID0 , IMX_SC_PM_CLK_MISC ) ;
2018-12-13 18:42:58 +03:00
for ( i = 0 ; i < clk_data - > num ; i + + ) {
if ( IS_ERR ( clks [ i ] ) )
pr_warn ( " i.MX clk %u: register failed with %ld \n " ,
i , PTR_ERR ( clks [ i ] ) ) ;
}
return of_clk_add_hw_provider ( ccm_node , of_clk_hw_onecell_get , clk_data ) ;
}
static const struct of_device_id imx8qxp_match [ ] = {
{ . compatible = " fsl,imx8qxp-clk " , } ,
{ /* sentinel */ }
} ;
static struct platform_driver imx8qxp_clk_driver = {
. driver = {
. name = " imx8qxp-clk " ,
. of_match_table = imx8qxp_match ,
. suppress_bind_attrs = true ,
} ,
. probe = imx8qxp_clk_probe ,
} ;
builtin_platform_driver ( imx8qxp_clk_driver ) ;