2011-02-26 01:39:28 +03:00
/*
* OMAP2 / 3 interface clock control
*
* Copyright ( C ) 2011 Nokia Corporation
* Paul Walmsley
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# undef DEBUG
# include <linux/kernel.h>
2012-11-11 03:58:41 +04:00
# include <linux/clk-provider.h>
2011-02-26 01:39:28 +03:00
# include <linux/io.h>
2015-03-02 15:33:54 +03:00
# include <linux/clk/ti.h>
2011-02-26 01:39:28 +03:00
# include "clock.h"
2014-07-02 12:47:47 +04:00
/* Register offsets */
2015-03-03 17:08:42 +03:00
# define OMAP24XX_CM_FCLKEN2 0x04
2014-07-02 12:47:47 +04:00
# define CM_AUTOIDLE 0x30
# define CM_ICLKEN 0x10
2015-03-03 17:08:42 +03:00
# define CM_IDLEST 0x20
# define OMAP24XX_CM_IDLEST_VAL 0
2011-02-26 01:39:28 +03:00
/* Private functions */
/* XXX */
2012-04-27 14:23:48 +04:00
void omap2_clkt_iclk_allow_idle ( struct clk_hw_omap * clk )
2011-02-26 01:39:28 +03:00
{
2013-10-22 12:49:58 +04:00
u32 v ;
2017-02-09 12:24:37 +03:00
struct clk_omap_reg r ;
2011-02-26 01:39:28 +03:00
2017-02-09 12:24:37 +03:00
memcpy ( & r , & clk - > enable_reg , sizeof ( r ) ) ;
r . offset ^ = ( CM_AUTOIDLE ^ CM_ICLKEN ) ;
2011-02-26 01:39:28 +03:00
2017-02-09 12:24:37 +03:00
v = ti_clk_ll_ops - > clk_readl ( & r ) ;
2011-02-26 01:39:28 +03:00
v | = ( 1 < < clk - > enable_bit ) ;
2017-02-09 12:24:37 +03:00
ti_clk_ll_ops - > clk_writel ( v , & r ) ;
2011-02-26 01:39:28 +03:00
}
/* XXX */
2012-04-27 14:23:48 +04:00
void omap2_clkt_iclk_deny_idle ( struct clk_hw_omap * clk )
2011-02-26 01:39:28 +03:00
{
2013-10-22 12:49:58 +04:00
u32 v ;
2017-02-09 12:24:37 +03:00
struct clk_omap_reg r ;
2011-02-26 01:39:28 +03:00
2017-02-09 12:24:37 +03:00
memcpy ( & r , & clk - > enable_reg , sizeof ( r ) ) ;
2011-02-26 01:39:28 +03:00
2017-02-09 12:24:37 +03:00
r . offset ^ = ( CM_AUTOIDLE ^ CM_ICLKEN ) ;
v = ti_clk_ll_ops - > clk_readl ( & r ) ;
2011-02-26 01:39:28 +03:00
v & = ~ ( 1 < < clk - > enable_bit ) ;
2017-02-09 12:24:37 +03:00
ti_clk_ll_ops - > clk_writel ( v , & r ) ;
2011-02-26 01:39:28 +03:00
}
2015-03-03 17:08:42 +03:00
/**
* omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
* @ clk : struct clk * being enabled
* @ idlest_reg : void __iomem * * to store CM_IDLEST reg address into
* @ idlest_bit : pointer to a u8 to store the CM_IDLEST bit shift into
* @ idlest_val : pointer to a u8 to store the CM_IDLEST indicator
*
* OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE , but the
* CM_ * CLKEN bits are in CM_ { I , F } CLKEN2_CORE . This custom function
* passes back the correct CM_IDLEST register address for I2CHS
* modules . No return value .
*/
static void omap2430_clk_i2chs_find_idlest ( struct clk_hw_omap * clk ,
2017-02-09 12:24:37 +03:00
struct clk_omap_reg * idlest_reg ,
2015-03-03 17:08:42 +03:00
u8 * idlest_bit ,
u8 * idlest_val )
{
2017-02-09 12:24:37 +03:00
memcpy ( idlest_reg , & clk - > enable_reg , sizeof ( * idlest_reg ) ) ;
idlest_reg - > offset ^ = ( OMAP24XX_CM_FCLKEN2 ^ CM_IDLEST ) ;
2015-03-03 17:08:42 +03:00
* idlest_bit = clk - > enable_bit ;
* idlest_val = OMAP24XX_CM_IDLEST_VAL ;
}
2011-02-26 01:39:28 +03:00
/* Public data */
2012-04-27 14:23:48 +04:00
const struct clk_hw_omap_ops clkhwops_iclk = {
. allow_idle = omap2_clkt_iclk_allow_idle ,
. deny_idle = omap2_clkt_iclk_deny_idle ,
} ;
2012-11-11 03:58:41 +04:00
const struct clk_hw_omap_ops clkhwops_iclk_wait = {
. allow_idle = omap2_clkt_iclk_allow_idle ,
. deny_idle = omap2_clkt_iclk_deny_idle ,
. find_idlest = omap2_clk_dflt_find_idlest ,
. find_companion = omap2_clk_dflt_find_companion ,
} ;
2015-03-03 17:08:42 +03:00
/* 2430 I2CHS has non-standard IDLEST register */
const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
. find_idlest = omap2430_clk_i2chs_find_idlest ,
. find_companion = omap2_clk_dflt_find_companion ,
} ;