2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2012-06-11 17:29:54 +02:00
/*
* Driver for the ICST307 VCO clock found in the ARM Reference designs .
* We wrap the custom interface from < asm / hardware / icst . h > into the generic
* clock framework .
*
2015-10-13 14:29:54 +02:00
* Copyright ( C ) 2012 - 2015 Linus Walleij
2012-11-20 22:39:31 +01:00
*
2012-06-11 17:29:54 +02:00
* TODO : when all ARM reference designs are migrated to generic clocks , the
* ICST clock code from the ARM tree should probably be merged into this
* file .
*/
2015-06-19 15:00:46 -07:00
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/export.h>
2012-06-11 17:29:54 +02:00
# include <linux/err.h>
# include <linux/clk-provider.h>
2012-11-20 23:01:04 +01:00
# include <linux/io.h>
2015-10-12 15:52:50 +02:00
# include <linux/regmap.h>
2015-10-12 16:14:28 +02:00
# include <linux/mfd/syscon.h>
2012-06-11 17:29:54 +02:00
2017-02-01 10:41:43 +01:00
# include "icst.h"
2012-06-11 17:29:54 +02:00
# include "clk-icst.h"
2015-10-12 15:52:50 +02:00
/* Magic unlocking token used on all Versatile boards */
# define VERSATILE_LOCK_VAL 0xA05F
2016-08-22 11:19:33 +02:00
# define VERSATILE_AUX_OSC_BITS 0x7FFFF
# define INTEGRATOR_AP_CM_BITS 0xFF
2016-08-27 14:01:19 +02:00
# define INTEGRATOR_AP_SYS_BITS 0xFF
2016-08-22 11:19:33 +02:00
# define INTEGRATOR_CP_CM_CORE_BITS 0x7FF
# define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000
2016-08-27 14:01:19 +02:00
# define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8)
2012-06-11 17:29:54 +02:00
/**
* struct clk_icst - ICST VCO clock wrapper
* @ hw : corresponding clock hardware entry
2021-01-20 09:30:39 +00:00
* @ map : register map
* @ vcoreg_off : VCO register address
* @ lockreg_off : VCO lock register address
2012-06-11 17:29:54 +02:00
* @ params : parameters for this ICST instance
* @ rate : current rate
2016-08-22 11:19:33 +02:00
* @ ctype : the type of control register for the ICST
2012-06-11 17:29:54 +02:00
*/
struct clk_icst {
struct clk_hw hw ;
2015-10-12 15:52:50 +02:00
struct regmap * map ;
u32 vcoreg_off ;
u32 lockreg_off ;
2014-01-20 21:46:46 +01:00
struct icst_params * params ;
2012-06-11 17:29:54 +02:00
unsigned long rate ;
2016-08-22 11:19:33 +02:00
enum icst_control_type ctype ;
2012-06-11 17:29:54 +02:00
} ;
# define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
2012-11-20 23:01:04 +01:00
/**
2015-10-12 15:52:50 +02:00
* vco_get ( ) - get ICST VCO settings from a certain ICST
* @ icst : the ICST clock to get
* @ vco : the VCO struct to return the value in
2012-11-20 23:01:04 +01:00
*/
2015-10-12 15:52:50 +02:00
static int vco_get ( struct clk_icst * icst , struct icst_vco * vco )
2012-11-20 23:01:04 +01:00
{
u32 val ;
2015-10-12 15:52:50 +02:00
int ret ;
ret = regmap_read ( icst - > map , icst - > vcoreg_off , & val ) ;
if ( ret )
return ret ;
2016-08-22 11:19:33 +02:00
/*
* The Integrator / AP core clock can only access the low eight
* bits of the v PLL divider . Bit 8 is tied low and always zero ,
* r is hardwired to 22 and output divider s is hardwired to 1
* ( divide by 2 ) according to the document
* " Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and
* CM1136JF - S User Guide " ARM DUI 0138E, page 3-13 thru 3-14.
*/
if ( icst - > ctype = = ICST_INTEGRATOR_AP_CM ) {
vco - > v = val & INTEGRATOR_AP_CM_BITS ;
vco - > r = 22 ;
vco - > s = 1 ;
return 0 ;
}
2016-08-27 14:01:19 +02:00
/*
* The Integrator / AP system clock on the base board can only
* access the low eight bits of the v PLL divider . Bit 8 is tied low
* and always zero , r is hardwired to 46 , and the output divider is
* hardwired to 3 ( divide by 4 ) according to the document
* " Integrator AP ASIC Development Motherboard " ARM DUI 00 98 B ,
* page 3 - 16.
*/
if ( icst - > ctype = = ICST_INTEGRATOR_AP_SYS ) {
vco - > v = val & INTEGRATOR_AP_SYS_BITS ;
vco - > r = 46 ;
vco - > s = 3 ;
return 0 ;
}
/*
* The Integrator / AP PCI clock is using an odd pattern to create
* the child clock , basically a single bit called DIVX / Y is used
* to select between two different hardwired values : setting the
* bit to 0 yields v = 17 , r = 22 and OD = 1 , whereas setting the
* bit to 1 yields v = 14 , r = 14 and OD = 1 giving the frequencies
* 33 or 25 MHz respectively .
*/
if ( icst - > ctype = = ICST_INTEGRATOR_AP_PCI ) {
bool divxy = ! ! ( val & INTEGRATOR_AP_PCI_25_33_MHZ ) ;
vco - > v = divxy ? 17 : 14 ;
vco - > r = divxy ? 22 : 14 ;
vco - > s = 1 ;
return 0 ;
}
2016-08-22 11:19:33 +02:00
/*
* The Integrator / CP core clock can access the low eight bits
* of the v PLL divider . Bit 8 is tied low and always zero ,
* r is hardwired to 22 and the output divider s is accessible
* in bits 8 thru 10 according to the document
* " Integrator/CM940T, CM920T, CM740T, and CM720T User Guide "
* ARM DUI 0157 A , page 3 - 20 thru 3 - 23 and 4 - 10.
*/
if ( icst - > ctype = = ICST_INTEGRATOR_CP_CM_CORE ) {
vco - > v = val & 0xFF ;
vco - > r = 22 ;
vco - > s = ( val > > 8 ) & 7 ;
return 0 ;
}
if ( icst - > ctype = = ICST_INTEGRATOR_CP_CM_MEM ) {
vco - > v = ( val > > 12 ) & 0xFF ;
vco - > r = 22 ;
vco - > s = ( val > > 20 ) & 7 ;
return 0 ;
}
2015-10-12 15:52:50 +02:00
vco - > v = val & 0x1ff ;
vco - > r = ( val > > 9 ) & 0x7f ;
vco - > s = ( val > > 16 ) & 03 ;
return 0 ;
2012-11-20 23:01:04 +01:00
}
/**
* vco_set ( ) - commit changes to an ICST VCO
2015-10-12 15:52:50 +02:00
* @ icst : the ICST clock to set
* @ vco : the VCO struct to set the changes from
2012-11-20 23:01:04 +01:00
*/
2015-10-12 15:52:50 +02:00
static int vco_set ( struct clk_icst * icst , struct icst_vco vco )
2012-11-20 23:01:04 +01:00
{
2016-08-22 11:19:33 +02:00
u32 mask ;
2012-11-20 23:01:04 +01:00
u32 val ;
2015-10-12 15:52:50 +02:00
int ret ;
2012-11-20 23:01:04 +01:00
2016-08-22 11:19:33 +02:00
/* Mask the bits used by the VCO */
switch ( icst - > ctype ) {
case ICST_INTEGRATOR_AP_CM :
mask = INTEGRATOR_AP_CM_BITS ;
val = vco . v & 0xFF ;
if ( vco . v & 0x100 )
pr_err ( " ICST error: tried to set bit 8 of VDW \n " ) ;
if ( vco . s ! = 1 )
pr_err ( " ICST error: tried to use VOD != 1 \n " ) ;
if ( vco . r ! = 22 )
pr_err ( " ICST error: tried to use RDW != 22 \n " ) ;
break ;
2016-08-27 14:01:19 +02:00
case ICST_INTEGRATOR_AP_SYS :
mask = INTEGRATOR_AP_SYS_BITS ;
val = vco . v & 0xFF ;
if ( vco . v & 0x100 )
pr_err ( " ICST error: tried to set bit 8 of VDW \n " ) ;
if ( vco . s ! = 3 )
pr_err ( " ICST error: tried to use VOD != 1 \n " ) ;
if ( vco . r ! = 46 )
pr_err ( " ICST error: tried to use RDW != 22 \n " ) ;
break ;
2016-08-22 11:19:33 +02:00
case ICST_INTEGRATOR_CP_CM_CORE :
mask = INTEGRATOR_CP_CM_CORE_BITS ; /* Uses 12 bits */
val = ( vco . v & 0xFF ) | vco . s < < 8 ;
if ( vco . v & 0x100 )
pr_err ( " ICST error: tried to set bit 8 of VDW \n " ) ;
if ( vco . r ! = 22 )
pr_err ( " ICST error: tried to use RDW != 22 \n " ) ;
break ;
case ICST_INTEGRATOR_CP_CM_MEM :
mask = INTEGRATOR_CP_CM_MEM_BITS ; /* Uses 12 bits */
val = ( ( vco . v & 0xFF ) < < 12 ) | ( vco . s < < 20 ) ;
if ( vco . v & 0x100 )
pr_err ( " ICST error: tried to set bit 8 of VDW \n " ) ;
if ( vco . r ! = 22 )
pr_err ( " ICST error: tried to use RDW != 22 \n " ) ;
break ;
default :
/* Regular auxilary oscillator */
mask = VERSATILE_AUX_OSC_BITS ;
val = vco . v | ( vco . r < < 9 ) | ( vco . s < < 16 ) ;
break ;
}
2016-02-03 14:47:08 +01:00
2016-08-22 11:19:33 +02:00
pr_debug ( " ICST: new val = 0x%08x \n " , val ) ;
2012-11-20 23:01:04 +01:00
/* This magic unlocks the VCO so it can be controlled */
2015-10-12 15:52:50 +02:00
ret = regmap_write ( icst - > map , icst - > lockreg_off , VERSATILE_LOCK_VAL ) ;
if ( ret )
return ret ;
2016-08-22 11:19:33 +02:00
ret = regmap_update_bits ( icst - > map , icst - > vcoreg_off , mask , val ) ;
2015-10-12 15:52:50 +02:00
if ( ret )
return ret ;
2012-11-20 23:01:04 +01:00
/* This locks the VCO again */
2015-10-12 15:52:50 +02:00
ret = regmap_write ( icst - > map , icst - > lockreg_off , 0 ) ;
if ( ret )
return ret ;
return 0 ;
2012-11-20 23:01:04 +01:00
}
2012-06-11 17:29:54 +02:00
static unsigned long icst_recalc_rate ( struct clk_hw * hw ,
unsigned long parent_rate )
{
struct clk_icst * icst = to_icst ( hw ) ;
struct icst_vco vco ;
2015-10-12 15:52:50 +02:00
int ret ;
2012-06-11 17:29:54 +02:00
2014-01-20 21:46:46 +01:00
if ( parent_rate )
icst - > params - > ref = parent_rate ;
2015-10-12 15:52:50 +02:00
ret = vco_get ( icst , & vco ) ;
if ( ret ) {
pr_err ( " ICST: could not get VCO setting \n " ) ;
return 0 ;
}
2012-06-11 17:29:54 +02:00
icst - > rate = icst_hz ( icst - > params , vco ) ;
return icst - > rate ;
}
static long icst_round_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long * prate )
{
struct clk_icst * icst = to_icst ( hw ) ;
struct icst_vco vco ;
2016-08-22 11:19:33 +02:00
if ( icst - > ctype = = ICST_INTEGRATOR_AP_CM | |
icst - > ctype = = ICST_INTEGRATOR_CP_CM_CORE ) {
if ( rate < = 12000000 )
return 12000000 ;
if ( rate > = 160000000 )
return 160000000 ;
/* Slam to closest megahertz */
return DIV_ROUND_CLOSEST ( rate , 1000000 ) * 1000000 ;
}
if ( icst - > ctype = = ICST_INTEGRATOR_CP_CM_MEM ) {
if ( rate < = 6000000 )
return 6000000 ;
if ( rate > = 66000000 )
return 66000000 ;
/* Slam to closest 0.5 megahertz */
return DIV_ROUND_CLOSEST ( rate , 500000 ) * 500000 ;
}
2016-08-27 14:01:19 +02:00
if ( icst - > ctype = = ICST_INTEGRATOR_AP_SYS ) {
/* Divides between 3 and 50 MHz in steps of 0.25 MHz */
if ( rate < = 3000000 )
return 3000000 ;
if ( rate > = 50000000 )
return 5000000 ;
/* Slam to closest 0.25 MHz */
return DIV_ROUND_CLOSEST ( rate , 250000 ) * 250000 ;
}
if ( icst - > ctype = = ICST_INTEGRATOR_AP_PCI ) {
/*
* If we ' re below or less than halfway from 25 to 33 MHz
* select 25 MHz
*/
if ( rate < = 25000000 | | rate < 29000000 )
return 25000000 ;
/* Else just return the default frequency */
return 33000000 ;
}
2012-06-11 17:29:54 +02:00
vco = icst_hz_to_vco ( icst - > params , rate ) ;
return icst_hz ( icst - > params , vco ) ;
}
static int icst_set_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long parent_rate )
{
struct clk_icst * icst = to_icst ( hw ) ;
struct icst_vco vco ;
2016-08-27 14:01:19 +02:00
if ( icst - > ctype = = ICST_INTEGRATOR_AP_PCI ) {
/* This clock is especially primitive */
unsigned int val ;
int ret ;
if ( rate = = 25000000 ) {
val = 0 ;
} else if ( rate = = 33000000 ) {
val = INTEGRATOR_AP_PCI_25_33_MHZ ;
} else {
pr_err ( " ICST: cannot set PCI frequency %lu \n " ,
rate ) ;
return - EINVAL ;
}
ret = regmap_write ( icst - > map , icst - > lockreg_off ,
VERSATILE_LOCK_VAL ) ;
if ( ret )
return ret ;
ret = regmap_update_bits ( icst - > map , icst - > vcoreg_off ,
INTEGRATOR_AP_PCI_25_33_MHZ ,
val ) ;
if ( ret )
return ret ;
/* This locks the VCO again */
ret = regmap_write ( icst - > map , icst - > lockreg_off , 0 ) ;
if ( ret )
return ret ;
return 0 ;
}
2014-01-20 21:46:46 +01:00
if ( parent_rate )
icst - > params - > ref = parent_rate ;
2012-06-11 17:29:54 +02:00
vco = icst_hz_to_vco ( icst - > params , rate ) ;
icst - > rate = icst_hz ( icst - > params , vco ) ;
2015-10-12 15:52:50 +02:00
return vco_set ( icst , vco ) ;
2012-06-11 17:29:54 +02:00
}
static const struct clk_ops icst_ops = {
. recalc_rate = icst_recalc_rate ,
. round_rate = icst_round_rate ,
. set_rate = icst_set_rate ,
} ;
2020-02-19 11:33:25 +01:00
struct clk * icst_clk_setup ( struct device * dev ,
const struct clk_icst_desc * desc ,
const char * name ,
const char * parent_name ,
struct regmap * map ,
enum icst_control_type ctype )
2012-06-11 17:29:54 +02:00
{
struct clk * clk ;
struct clk_icst * icst ;
struct clk_init_data init ;
2014-01-20 21:46:46 +01:00
struct icst_params * pclone ;
2012-06-11 17:29:54 +02:00
2017-09-27 21:24:43 +02:00
icst = kzalloc ( sizeof ( * icst ) , GFP_KERNEL ) ;
2017-09-27 21:21:23 +02:00
if ( ! icst )
2012-06-11 17:29:54 +02:00
return ERR_PTR ( - ENOMEM ) ;
2014-01-20 21:46:46 +01:00
pclone = kmemdup ( desc - > params , sizeof ( * pclone ) , GFP_KERNEL ) ;
if ( ! pclone ) {
2014-04-12 18:59:14 +01:00
kfree ( icst ) ;
2014-01-20 21:46:46 +01:00
return ERR_PTR ( - ENOMEM ) ;
}
2013-11-22 11:30:05 +01:00
init . name = name ;
2012-06-11 17:29:54 +02:00
init . ops = & icst_ops ;
2016-03-01 11:00:05 -08:00
init . flags = 0 ;
2014-01-20 21:46:46 +01:00
init . parent_names = ( parent_name ? & parent_name : NULL ) ;
init . num_parents = ( parent_name ? 1 : 0 ) ;
2015-10-12 16:14:28 +02:00
icst - > map = map ;
2012-06-11 17:29:54 +02:00
icst - > hw . init = & init ;
2014-01-20 21:46:46 +01:00
icst - > params = pclone ;
2015-10-12 15:52:50 +02:00
icst - > vcoreg_off = desc - > vco_offset ;
icst - > lockreg_off = desc - > lock_offset ;
2016-08-22 11:19:33 +02:00
icst - > ctype = ctype ;
2012-06-11 17:29:54 +02:00
clk = clk_register ( dev , & icst - > hw ) ;
2015-10-23 11:36:01 +02:00
if ( IS_ERR ( clk ) ) {
kfree ( pclone ) ;
2012-06-11 17:29:54 +02:00
kfree ( icst ) ;
2015-10-23 11:36:01 +02:00
}
2012-06-11 17:29:54 +02:00
return clk ;
}
2020-02-19 11:33:25 +01:00
EXPORT_SYMBOL_GPL ( icst_clk_setup ) ;
2015-10-12 16:14:28 +02:00
struct clk * icst_clk_register ( struct device * dev ,
const struct clk_icst_desc * desc ,
const char * name ,
const char * parent_name ,
void __iomem * base )
{
struct regmap_config icst_regmap_conf = {
. reg_bits = 32 ,
. val_bits = 32 ,
. reg_stride = 4 ,
} ;
struct regmap * map ;
map = regmap_init_mmio ( dev , base , & icst_regmap_conf ) ;
if ( IS_ERR ( map ) ) {
pr_err ( " could not initialize ICST regmap \n " ) ;
return ERR_CAST ( map ) ;
}
2016-08-22 11:19:33 +02:00
return icst_clk_setup ( dev , desc , name , parent_name , map ,
ICST_VERSATILE ) ;
2015-10-12 16:14:28 +02:00
}
2014-05-08 16:56:16 +02:00
EXPORT_SYMBOL_GPL ( icst_clk_register ) ;
2015-10-13 14:29:54 +02:00
# ifdef CONFIG_OF
/*
* In a device tree , an memory - mapped ICST clock appear as a child
* of a syscon node . Assume this and probe it only as a child of a
* syscon .
*/
static const struct icst_params icst525_params = {
. vco_max = ICST525_VCO_MAX_5V ,
. vco_min = ICST525_VCO_MIN ,
. vd_min = 8 ,
. vd_max = 263 ,
. rd_min = 3 ,
. rd_max = 65 ,
. s2div = icst525_s2div ,
. idx2s = icst525_idx2s ,
} ;
static const struct icst_params icst307_params = {
. vco_max = ICST307_VCO_MAX ,
. vco_min = ICST307_VCO_MIN ,
. vd_min = 4 + 8 ,
. vd_max = 511 + 8 ,
. rd_min = 1 + 2 ,
. rd_max = 127 + 2 ,
. s2div = icst307_s2div ,
. idx2s = icst307_idx2s ,
} ;
2021-01-20 09:30:39 +00:00
/*
2016-08-22 11:19:33 +02:00
* The core modules on the Integrator / AP and Integrator / CP have
* especially crippled ICST525 control .
*/
static const struct icst_params icst525_apcp_cm_params = {
. vco_max = ICST525_VCO_MAX_5V ,
. vco_min = ICST525_VCO_MIN ,
/* Minimum 12 MHz, VDW = 4 */
. vd_min = 12 ,
/*
* Maximum 160 MHz , VDW = 152 for all core modules , but
* CM926EJ - S , CM1026EJ - S and CM1136JF - S can actually
* go to 200 MHz ( max VDW = 192 ) .
*/
. vd_max = 192 ,
/* r is hardcoded to 22 and this is the actual divisor, +2 */
. rd_min = 24 ,
. rd_max = 24 ,
. s2div = icst525_s2div ,
. idx2s = icst525_idx2s ,
} ;
2016-08-27 14:01:19 +02:00
static const struct icst_params icst525_ap_sys_params = {
. vco_max = ICST525_VCO_MAX_5V ,
. vco_min = ICST525_VCO_MIN ,
/* Minimum 3 MHz, VDW = 4 */
. vd_min = 3 ,
/* Maximum 50 MHz, VDW = 192 */
. vd_max = 50 ,
/* r is hardcoded to 46 and this is the actual divisor, +2 */
. rd_min = 48 ,
. rd_max = 48 ,
. s2div = icst525_s2div ,
. idx2s = icst525_idx2s ,
} ;
static const struct icst_params icst525_ap_pci_params = {
. vco_max = ICST525_VCO_MAX_5V ,
. vco_min = ICST525_VCO_MIN ,
/* Minimum 25 MHz */
. vd_min = 25 ,
/* Maximum 33 MHz */
. vd_max = 33 ,
/* r is hardcoded to 14 or 22 and this is the actual divisors +2 */
. rd_min = 16 ,
. rd_max = 24 ,
. s2div = icst525_s2div ,
. idx2s = icst525_idx2s ,
} ;
2015-10-13 14:29:54 +02:00
static void __init of_syscon_icst_setup ( struct device_node * np )
{
struct device_node * parent ;
struct regmap * map ;
struct clk_icst_desc icst_desc ;
2021-11-09 10:46:50 -06:00
const char * name ;
2015-10-13 14:29:54 +02:00
const char * parent_name ;
struct clk * regclk ;
2016-08-22 11:19:33 +02:00
enum icst_control_type ctype ;
2015-10-13 14:29:54 +02:00
/* We do not release this reference, we are using it perpetually */
parent = of_get_parent ( np ) ;
if ( ! parent ) {
pr_err ( " no parent node for syscon ICST clock \n " ) ;
return ;
}
map = syscon_node_to_regmap ( parent ) ;
if ( IS_ERR ( map ) ) {
pr_err ( " no regmap for syscon ICST clock parent \n " ) ;
return ;
}
2021-09-13 14:28:13 -05:00
if ( of_property_read_u32 ( np , " reg " , & icst_desc . vco_offset ) & &
of_property_read_u32 ( np , " vco-offset " , & icst_desc . vco_offset ) ) {
2015-10-13 14:29:54 +02:00
pr_err ( " no VCO register offset for ICST clock \n " ) ;
return ;
}
if ( of_property_read_u32 ( np , " lock-offset " , & icst_desc . lock_offset ) ) {
pr_err ( " no lock register offset for ICST clock \n " ) ;
return ;
}
2016-08-22 11:19:33 +02:00
if ( of_device_is_compatible ( np , " arm,syscon-icst525 " ) ) {
2015-10-13 14:29:54 +02:00
icst_desc . params = & icst525_params ;
2016-08-22 11:19:33 +02:00
ctype = ICST_VERSATILE ;
} else if ( of_device_is_compatible ( np , " arm,syscon-icst307 " ) ) {
2015-10-13 14:29:54 +02:00
icst_desc . params = & icst307_params ;
2016-08-22 11:19:33 +02:00
ctype = ICST_VERSATILE ;
} else if ( of_device_is_compatible ( np , " arm,syscon-icst525-integratorap-cm " ) ) {
icst_desc . params = & icst525_apcp_cm_params ;
ctype = ICST_INTEGRATOR_AP_CM ;
2016-08-27 14:01:19 +02:00
} else if ( of_device_is_compatible ( np , " arm,syscon-icst525-integratorap-sys " ) ) {
icst_desc . params = & icst525_ap_sys_params ;
ctype = ICST_INTEGRATOR_AP_SYS ;
} else if ( of_device_is_compatible ( np , " arm,syscon-icst525-integratorap-pci " ) ) {
icst_desc . params = & icst525_ap_pci_params ;
ctype = ICST_INTEGRATOR_AP_PCI ;
2016-08-22 11:19:33 +02:00
} else if ( of_device_is_compatible ( np , " arm,syscon-icst525-integratorcp-cm-core " ) ) {
icst_desc . params = & icst525_apcp_cm_params ;
ctype = ICST_INTEGRATOR_CP_CM_CORE ;
} else if ( of_device_is_compatible ( np , " arm,syscon-icst525-integratorcp-cm-mem " ) ) {
icst_desc . params = & icst525_apcp_cm_params ;
ctype = ICST_INTEGRATOR_CP_CM_MEM ;
} else {
2021-11-09 10:46:50 -06:00
pr_err ( " unknown ICST clock %pOF \n " , np ) ;
2015-10-13 14:29:54 +02:00
return ;
}
/* Parent clock name is not the same as node parent */
parent_name = of_clk_get_parent_name ( np , 0 ) ;
2021-11-09 10:46:50 -06:00
name = kasprintf ( GFP_KERNEL , " %pOFP " , np ) ;
2015-10-13 14:29:54 +02:00
2016-08-22 11:19:33 +02:00
regclk = icst_clk_setup ( NULL , & icst_desc , name , parent_name , map , ctype ) ;
2015-10-13 14:29:54 +02:00
if ( IS_ERR ( regclk ) ) {
pr_err ( " error setting up syscon ICST clock %s \n " , name ) ;
2021-11-17 10:26:05 +03:00
kfree ( name ) ;
2015-10-13 14:29:54 +02:00
return ;
}
of_clk_add_provider ( np , of_clk_src_simple_get , regclk ) ;
pr_debug ( " registered syscon ICST clock %s \n " , name ) ;
}
CLK_OF_DECLARE ( arm_syscon_icst525_clk ,
" arm,syscon-icst525 " , of_syscon_icst_setup ) ;
CLK_OF_DECLARE ( arm_syscon_icst307_clk ,
" arm,syscon-icst307 " , of_syscon_icst_setup ) ;
2016-08-22 11:19:33 +02:00
CLK_OF_DECLARE ( arm_syscon_integratorap_cm_clk ,
" arm,syscon-icst525-integratorap-cm " , of_syscon_icst_setup ) ;
2016-08-27 14:01:19 +02:00
CLK_OF_DECLARE ( arm_syscon_integratorap_sys_clk ,
" arm,syscon-icst525-integratorap-sys " , of_syscon_icst_setup ) ;
CLK_OF_DECLARE ( arm_syscon_integratorap_pci_clk ,
" arm,syscon-icst525-integratorap-pci " , of_syscon_icst_setup ) ;
2016-08-22 11:19:33 +02:00
CLK_OF_DECLARE ( arm_syscon_integratorcp_cm_core_clk ,
" arm,syscon-icst525-integratorcp-cm-core " , of_syscon_icst_setup ) ;
CLK_OF_DECLARE ( arm_syscon_integratorcp_cm_mem_clk ,
" arm,syscon-icst525-integratorcp-cm-mem " , of_syscon_icst_setup ) ;
2015-10-13 14:29:54 +02:00
# endif