2023-03-06 15:05:39 +01:00
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright ( c ) 2014 MediaTek Inc .
* James Liao < jamesjj . liao @ mediatek . com >
* Copyright ( c ) 2023 Collabora , Ltd .
* AngeloGioacchino Del Regno < angelogioacchino . delregno @ collabora . com >
*/
# include <dt-bindings/clock/mt8135-clk.h>
# include <linux/clk.h>
# include <linux/of.h>
# include <linux/platform_device.h>
# include "clk-mtk.h"
# include "clk-pll.h"
# define MT8135_PLL_FMAX (2000 * MHZ)
# define CON0_MT8135_RST_BAR BIT(27)
# define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
. id = _id , \
. name = _name , \
. reg = _reg , \
. pwr_reg = _pwr_reg , \
. en_mask = _en_mask , \
. flags = _flags , \
. rst_bar_mask = CON0_MT8135_RST_BAR , \
. fmax = MT8135_PLL_FMAX , \
. pcwbits = _pcwbits , \
. pd_reg = _pd_reg , \
. pd_shift = _pd_shift , \
. tuner_reg = _tuner_reg , \
. pcw_reg = _pcw_reg , \
. pcw_shift = _pcw_shift , \
}
static const struct mtk_pll_data plls [ ] = {
PLL ( CLK_APMIXED_ARMPLL1 , " armpll1 " , 0x200 , 0x218 , 0x80000000 , 0 , 21 , 0x204 , 24 , 0x0 , 0x204 , 0 ) ,
PLL ( CLK_APMIXED_ARMPLL2 , " armpll2 " , 0x2cc , 0x2e4 , 0x80000000 , 0 , 21 , 0x2d0 , 24 , 0x0 , 0x2d0 , 0 ) ,
PLL ( CLK_APMIXED_MAINPLL , " mainpll " , 0x21c , 0x234 , 0xf0000000 , HAVE_RST_BAR , 21 , 0x21c , 6 , 0x0 , 0x220 , 0 ) ,
PLL ( CLK_APMIXED_UNIVPLL , " univpll " , 0x238 , 0x250 , 0xf3000000 , HAVE_RST_BAR , 7 , 0x238 , 6 , 0x0 , 0x238 , 9 ) ,
PLL ( CLK_APMIXED_MMPLL , " mmpll " , 0x254 , 0x26c , 0xf0000000 , HAVE_RST_BAR , 21 , 0x254 , 6 , 0x0 , 0x258 , 0 ) ,
PLL ( CLK_APMIXED_MSDCPLL , " msdcpll " , 0x278 , 0x290 , 0x80000000 , 0 , 21 , 0x278 , 6 , 0x0 , 0x27c , 0 ) ,
PLL ( CLK_APMIXED_TVDPLL , " tvdpll " , 0x294 , 0x2ac , 0x80000000 , 0 , 31 , 0x294 , 6 , 0x0 , 0x298 , 0 ) ,
PLL ( CLK_APMIXED_LVDSPLL , " lvdspll " , 0x2b0 , 0x2c8 , 0x80000000 , 0 , 21 , 0x2b0 , 6 , 0x0 , 0x2b4 , 0 ) ,
PLL ( CLK_APMIXED_AUDPLL , " audpll " , 0x2e8 , 0x300 , 0x80000000 , 0 , 31 , 0x2e8 , 6 , 0x2f8 , 0x2ec , 0 ) ,
PLL ( CLK_APMIXED_VDECPLL , " vdecpll " , 0x304 , 0x31c , 0x80000000 , 0 , 21 , 0x2b0 , 6 , 0x0 , 0x308 , 0 ) ,
} ;
2023-03-06 15:05:41 +01:00
static int clk_mt8135_apmixed_probe ( struct platform_device * pdev )
2023-03-06 15:05:39 +01:00
{
struct clk_hw_onecell_data * clk_data ;
2023-03-06 15:05:41 +01:00
struct device_node * node = pdev - > dev . of_node ;
int ret ;
2023-03-06 15:05:39 +01:00
clk_data = mtk_alloc_clk_data ( CLK_APMIXED_NR_CLK ) ;
if ( ! clk_data )
2023-03-06 15:05:41 +01:00
return - ENOMEM ;
2023-03-06 15:05:39 +01:00
2023-03-06 15:05:41 +01:00
ret = mtk_clk_register_plls ( node , plls , ARRAY_SIZE ( plls ) , clk_data ) ;
if ( ret )
return ret ;
ret = of_clk_add_hw_provider ( node , of_clk_hw_onecell_get , clk_data ) ;
if ( ret )
goto unregister_plls ;
return 0 ;
unregister_plls :
mtk_clk_unregister_plls ( plls , ARRAY_SIZE ( plls ) , clk_data ) ;
return ret ;
}
static int clk_mt8135_apmixed_remove ( struct platform_device * pdev )
{
struct device_node * node = pdev - > dev . of_node ;
struct clk_hw_onecell_data * clk_data = platform_get_drvdata ( pdev ) ;
of_clk_del_provider ( node ) ;
mtk_clk_unregister_plls ( plls , ARRAY_SIZE ( plls ) , clk_data ) ;
mtk_free_clk_data ( clk_data ) ;
return 0 ;
2023-03-06 15:05:39 +01:00
}
2023-03-06 15:05:41 +01:00
static const struct of_device_id of_match_clk_mt8135_apmixed [ ] = {
{ . compatible = " mediatek,mt8135-apmixedsys " } ,
{ /* sentinel */ }
} ;
MODULE_DEVICE_TABLE ( of , of_match_clk_mt8135_apmixed ) ;
static struct platform_driver clk_mt8135_apmixed_drv = {
. probe = clk_mt8135_apmixed_probe ,
. remove = clk_mt8135_apmixed_remove ,
. driver = {
. name = " clk-mt8135-apmixed " ,
. of_match_table = of_match_clk_mt8135_apmixed ,
} ,
} ;
module_platform_driver ( clk_mt8135_apmixed_drv )
MODULE_DESCRIPTION ( " MediaTek MT8135 apmixedsys clocks driver " ) ;
2023-03-06 15:05:39 +01:00
MODULE_LICENSE ( " GPL " ) ;