2019-05-29 07:17:56 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2014-09-11 15:48:55 -07:00
/*
* Rockchip IO Voltage Domain driver
*
* Copyright 2014 MundoReader S . L .
* Copyright 2014 Google , Inc .
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/err.h>
# include <linux/mfd/syscon.h>
# include <linux/of.h>
# include <linux/platform_device.h>
# include <linux/regmap.h>
# include <linux/regulator/consumer.h>
# define MAX_SUPPLIES 16
/*
* The max voltage for 1.8 V and 3.3 V come from the Rockchip datasheet under
* " Recommended Operating Conditions " for " Digital GPIO " . When the typical
* is 3.3 V the max is 3.6 V . When the typical is 1.8 V the max is 1.98 V .
*
* They are used like this :
* - If the voltage on a rail is above the " 1.8 " voltage ( 1.98 V ) we ' ll tell the
* SoC we ' re at 3.3 .
* - If the voltage on a rail is above the " 3.3 " voltage ( 3.6 V ) we ' ll consider
* that to be an error .
*/
# define MAX_VOLTAGE_1_8 1980000
# define MAX_VOLTAGE_3_3 3600000
2018-05-15 19:48:19 +08:00
# define PX30_IO_VSEL 0x180
# define PX30_IO_VSEL_VCCIO6_SRC BIT(0)
# define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1
2014-09-11 15:48:55 -07:00
# define RK3288_SOC_CON2 0x24c
# define RK3288_SOC_CON2_FLASH0 BIT(7)
# define RK3288_SOC_FLASH_SUPPLY_NUM 2
2017-02-23 20:33:11 +08:00
# define RK3328_SOC_CON4 0x410
# define RK3328_SOC_CON4_VCCIO2 BIT(7)
# define RK3328_SOC_VCCIO2_SUPPLY_NUM 1
2015-08-04 21:37:01 +02:00
# define RK3368_SOC_CON15 0x43c
# define RK3368_SOC_CON15_FLASH0 BIT(14)
# define RK3368_SOC_FLASH_SUPPLY_NUM 2
2016-03-16 02:45:26 +08:00
# define RK3399_PMUGRF_CON0 0x180
# define RK3399_PMUGRF_CON0_VSEL BIT(8)
# define RK3399_PMUGRF_VSEL_SUPPLY_NUM 9
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
# define RK3568_PMU_GRF_IO_VSEL0 (0x0140)
# define RK3568_PMU_GRF_IO_VSEL1 (0x0144)
# define RK3568_PMU_GRF_IO_VSEL2 (0x0148)
2014-09-11 15:48:55 -07:00
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
struct rockchip_iodomain ;
2014-09-11 15:48:55 -07:00
struct rockchip_iodomain_supply {
struct rockchip_iodomain * iod ;
struct regulator * reg ;
struct notifier_block nb ;
int idx ;
} ;
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
struct rockchip_iodomain_soc_data {
int grf_offset ;
const char * supply_names [ MAX_SUPPLIES ] ;
void ( * init ) ( struct rockchip_iodomain * iod ) ;
int ( * write ) ( struct rockchip_iodomain_supply * supply , int uV ) ;
} ;
2014-09-11 15:48:55 -07:00
struct rockchip_iodomain {
struct device * dev ;
struct regmap * grf ;
2018-01-02 14:27:57 +01:00
const struct rockchip_iodomain_soc_data * soc_data ;
2014-09-11 15:48:55 -07:00
struct rockchip_iodomain_supply supplies [ MAX_SUPPLIES ] ;
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
int ( * write ) ( struct rockchip_iodomain_supply * supply , int uV ) ;
2014-09-11 15:48:55 -07:00
} ;
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
static int rk3568_iodomain_write ( struct rockchip_iodomain_supply * supply , int uV )
{
struct rockchip_iodomain * iod = supply - > iod ;
u32 is_3v3 = uV > MAX_VOLTAGE_1_8 ;
u32 val0 , val1 ;
int b ;
switch ( supply - > idx ) {
case 0 : /* pmuio1 */
break ;
case 1 : /* pmuio2 */
b = supply - > idx ;
val0 = BIT ( 16 + b ) | ( is_3v3 ? 0 : BIT ( b ) ) ;
b = supply - > idx + 4 ;
val1 = BIT ( 16 + b ) | ( is_3v3 ? BIT ( b ) : 0 ) ;
regmap_write ( iod - > grf , RK3568_PMU_GRF_IO_VSEL2 , val0 ) ;
regmap_write ( iod - > grf , RK3568_PMU_GRF_IO_VSEL2 , val1 ) ;
break ;
case 3 : /* vccio2 */
break ;
case 2 : /* vccio1 */
case 4 : /* vccio3 */
case 5 : /* vccio4 */
case 6 : /* vccio5 */
case 7 : /* vccio6 */
case 8 : /* vccio7 */
b = supply - > idx - 1 ;
val0 = BIT ( 16 + b ) | ( is_3v3 ? 0 : BIT ( b ) ) ;
val1 = BIT ( 16 + b ) | ( is_3v3 ? BIT ( b ) : 0 ) ;
regmap_write ( iod - > grf , RK3568_PMU_GRF_IO_VSEL0 , val0 ) ;
regmap_write ( iod - > grf , RK3568_PMU_GRF_IO_VSEL1 , val1 ) ;
break ;
default :
return - EINVAL ;
2021-08-19 16:29:09 +08:00
}
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
return 0 ;
}
2014-09-11 15:48:55 -07:00
static int rockchip_iodomain_write ( struct rockchip_iodomain_supply * supply ,
int uV )
{
struct rockchip_iodomain * iod = supply - > iod ;
u32 val ;
int ret ;
/* set value bit */
val = ( uV > MAX_VOLTAGE_1_8 ) ? 0 : 1 ;
val < < = supply - > idx ;
/* apply hiword-mask */
val | = ( BIT ( supply - > idx ) < < 16 ) ;
ret = regmap_write ( iod - > grf , iod - > soc_data - > grf_offset , val ) ;
if ( ret )
dev_err ( iod - > dev , " Couldn't write to GRF \n " ) ;
return ret ;
}
static int rockchip_iodomain_notify ( struct notifier_block * nb ,
unsigned long event ,
void * data )
{
struct rockchip_iodomain_supply * supply =
container_of ( nb , struct rockchip_iodomain_supply , nb ) ;
int uV ;
int ret ;
/*
* According to Rockchip it ' s important to keep the SoC IO domain
* higher than ( or equal to ) the external voltage . That means we need
* to change it before external voltage changes happen in the case
* of an increase .
*
* Note that in the " pre " change we pick the max possible voltage that
* the regulator might end up at ( the client requests a range and we
* don ' t know for certain the exact voltage ) . Right now we rely on the
* slop in MAX_VOLTAGE_1_8 and MAX_VOLTAGE_3_3 to save us if clients
* request something like a max of 3.6 V when they really want 3.3 V .
* We could attempt to come up with better rules if this fails .
*/
if ( event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE ) {
struct pre_voltage_change_data * pvc_data = data ;
uV = max_t ( unsigned long , pvc_data - > old_uV , pvc_data - > max_uV ) ;
} else if ( event & ( REGULATOR_EVENT_VOLTAGE_CHANGE |
REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE ) ) {
uV = ( unsigned long ) data ;
} else {
return NOTIFY_OK ;
}
dev_dbg ( supply - > iod - > dev , " Setting to %d \n " , uV ) ;
if ( uV > MAX_VOLTAGE_3_3 ) {
dev_err ( supply - > iod - > dev , " Voltage too high: %d \n " , uV ) ;
if ( event = = REGULATOR_EVENT_PRE_VOLTAGE_CHANGE )
return NOTIFY_BAD ;
}
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
ret = supply - > iod - > write ( supply , uV ) ;
2014-09-11 15:48:55 -07:00
if ( ret & & event = = REGULATOR_EVENT_PRE_VOLTAGE_CHANGE )
return NOTIFY_BAD ;
2016-10-10 20:44:22 +08:00
dev_dbg ( supply - > iod - > dev , " Setting to %d done \n " , uV ) ;
2014-09-11 15:48:55 -07:00
return NOTIFY_OK ;
}
2018-05-15 19:48:19 +08:00
static void px30_iodomain_init ( struct rockchip_iodomain * iod )
{
int ret ;
u32 val ;
2020-01-21 23:28:59 +01:00
/* if no VCCIO6 supply we should leave things alone */
2018-05-15 19:48:19 +08:00
if ( ! iod - > supplies [ PX30_IO_VSEL_VCCIO6_SUPPLY_NUM ] . reg )
return ;
/*
2020-01-21 23:28:59 +01:00
* set vccio6 iodomain to also use this framework
2018-05-15 19:48:19 +08:00
* instead of a special gpio .
*/
val = PX30_IO_VSEL_VCCIO6_SRC | ( PX30_IO_VSEL_VCCIO6_SRC < < 16 ) ;
ret = regmap_write ( iod - > grf , PX30_IO_VSEL , val ) ;
if ( ret < 0 )
2020-01-21 23:28:59 +01:00
dev_warn ( iod - > dev , " couldn't update vccio6 ctrl \n " ) ;
2018-05-15 19:48:19 +08:00
}
2014-09-11 15:48:55 -07:00
static void rk3288_iodomain_init ( struct rockchip_iodomain * iod )
{
int ret ;
u32 val ;
/* if no flash supply we should leave things alone */
if ( ! iod - > supplies [ RK3288_SOC_FLASH_SUPPLY_NUM ] . reg )
return ;
/*
* set flash0 iodomain to also use this framework
* instead of a special gpio .
*/
val = RK3288_SOC_CON2_FLASH0 | ( RK3288_SOC_CON2_FLASH0 < < 16 ) ;
ret = regmap_write ( iod - > grf , RK3288_SOC_CON2 , val ) ;
if ( ret < 0 )
dev_warn ( iod - > dev , " couldn't update flash0 ctrl \n " ) ;
}
2017-02-23 20:33:11 +08:00
static void rk3328_iodomain_init ( struct rockchip_iodomain * iod )
{
int ret ;
u32 val ;
/* if no vccio2 supply we should leave things alone */
if ( ! iod - > supplies [ RK3328_SOC_VCCIO2_SUPPLY_NUM ] . reg )
return ;
/*
* set vccio2 iodomain to also use this framework
* instead of a special gpio .
*/
val = RK3328_SOC_CON4_VCCIO2 | ( RK3328_SOC_CON4_VCCIO2 < < 16 ) ;
ret = regmap_write ( iod - > grf , RK3328_SOC_CON4 , val ) ;
if ( ret < 0 )
dev_warn ( iod - > dev , " couldn't update vccio2 vsel ctrl \n " ) ;
}
2015-08-04 21:37:01 +02:00
static void rk3368_iodomain_init ( struct rockchip_iodomain * iod )
{
int ret ;
u32 val ;
/* if no flash supply we should leave things alone */
if ( ! iod - > supplies [ RK3368_SOC_FLASH_SUPPLY_NUM ] . reg )
return ;
/*
* set flash0 iodomain to also use this framework
* instead of a special gpio .
*/
val = RK3368_SOC_CON15_FLASH0 | ( RK3368_SOC_CON15_FLASH0 < < 16 ) ;
ret = regmap_write ( iod - > grf , RK3368_SOC_CON15 , val ) ;
if ( ret < 0 )
dev_warn ( iod - > dev , " couldn't update flash0 ctrl \n " ) ;
}
2016-03-16 02:45:26 +08:00
static void rk3399_pmu_iodomain_init ( struct rockchip_iodomain * iod )
{
int ret ;
u32 val ;
/* if no pmu io supply we should leave things alone */
if ( ! iod - > supplies [ RK3399_PMUGRF_VSEL_SUPPLY_NUM ] . reg )
return ;
/*
* set pmu io iodomain to also use this framework
* instead of a special gpio .
*/
val = RK3399_PMUGRF_CON0_VSEL | ( RK3399_PMUGRF_CON0_VSEL < < 16 ) ;
ret = regmap_write ( iod - > grf , RK3399_PMUGRF_CON0 , val ) ;
if ( ret < 0 )
dev_warn ( iod - > dev , " couldn't update pmu io iodomain ctrl \n " ) ;
}
2018-05-15 19:48:19 +08:00
static const struct rockchip_iodomain_soc_data soc_data_px30 = {
. grf_offset = 0x180 ,
. supply_names = {
NULL ,
" vccio6 " ,
" vccio1 " ,
" vccio2 " ,
" vccio3 " ,
" vccio4 " ,
" vccio5 " ,
" vccio-oscgpi " ,
} ,
. init = px30_iodomain_init ,
} ;
static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
. grf_offset = 0x100 ,
. supply_names = {
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
" pmuio1 " ,
" pmuio2 " ,
} ,
} ;
2014-09-11 15:48:55 -07:00
/*
* On the rk3188 the io - domains are handled by a shared register with the
* lower 8 bits being still being continuing drive - strength settings .
*/
static const struct rockchip_iodomain_soc_data soc_data_rk3188 = {
. grf_offset = 0x104 ,
. supply_names = {
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
" ap0 " ,
" ap1 " ,
" cif " ,
" flash " ,
" vccio0 " ,
" vccio1 " ,
" lcdc0 " ,
" lcdc1 " ,
} ,
} ;
2017-06-09 17:36:14 +08:00
static const struct rockchip_iodomain_soc_data soc_data_rk3228 = {
. grf_offset = 0x418 ,
. supply_names = {
" vccio1 " ,
" vccio2 " ,
" vccio3 " ,
" vccio4 " ,
} ,
} ;
2014-09-11 15:48:55 -07:00
static const struct rockchip_iodomain_soc_data soc_data_rk3288 = {
. grf_offset = 0x380 ,
. supply_names = {
" lcdc " , /* LCDC_VDD */
" dvp " , /* DVPIO_VDD */
" flash0 " , /* FLASH0_VDD (emmc) */
" flash1 " , /* FLASH1_VDD (sdio1) */
" wifi " , /* APIO3_VDD (sdio0) */
" bb " , /* APIO5_VDD */
" audio " , /* APIO4_VDD */
" sdcard " , /* SDMMC0_VDD (sdmmc) */
" gpio30 " , /* APIO1_VDD */
" gpio1830 " , /* APIO2_VDD */
} ,
. init = rk3288_iodomain_init ,
} ;
2017-02-23 20:33:11 +08:00
static const struct rockchip_iodomain_soc_data soc_data_rk3328 = {
. grf_offset = 0x410 ,
. supply_names = {
" vccio1 " ,
" vccio2 " ,
" vccio3 " ,
" vccio4 " ,
" vccio5 " ,
" vccio6 " ,
" pmuio " ,
} ,
. init = rk3328_iodomain_init ,
} ;
2015-08-04 21:37:01 +02:00
static const struct rockchip_iodomain_soc_data soc_data_rk3368 = {
. grf_offset = 0x900 ,
. supply_names = {
NULL , /* reserved */
" dvp " , /* DVPIO_VDD */
" flash0 " , /* FLASH0_VDD (emmc) */
" wifi " , /* APIO2_VDD (sdio0) */
NULL ,
" audio " , /* APIO3_VDD */
" sdcard " , /* SDMMC0_VDD (sdmmc) */
" gpio30 " , /* APIO1_VDD */
" gpio1830 " , /* APIO4_VDD (gpujtag) */
} ,
. init = rk3368_iodomain_init ,
} ;
static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = {
. grf_offset = 0x100 ,
. supply_names = {
NULL ,
NULL ,
NULL ,
NULL ,
" pmu " , /*PMU IO domain*/
" vop " , /*LCDC IO domain*/
} ,
} ;
2016-03-16 02:45:26 +08:00
static const struct rockchip_iodomain_soc_data soc_data_rk3399 = {
. grf_offset = 0xe640 ,
. supply_names = {
" bt656 " , /* APIO2_VDD */
" audio " , /* APIO5_VDD */
" sdmmc " , /* SDMMC0_VDD */
" gpio1830 " , /* APIO4_VDD */
} ,
} ;
static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
. grf_offset = 0x180 ,
. supply_names = {
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
" pmu1830 " , /* PMUIO2_VDD */
} ,
. init = rk3399_pmu_iodomain_init ,
} ;
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
. grf_offset = 0x140 ,
. supply_names = {
" pmuio1 " ,
" pmuio2 " ,
" vccio1 " ,
" vccio2 " ,
" vccio3 " ,
" vccio4 " ,
" vccio5 " ,
" vccio6 " ,
" vccio7 " ,
} ,
. write = rk3568_iodomain_write ,
} ;
2017-08-21 18:58:33 +08:00
static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
. grf_offset = 0x404 ,
. supply_names = {
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
" vccio1 " ,
" vccio2 " ,
" vccio3 " ,
" vccio5 " ,
" vccio6 " ,
} ,
} ;
static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
. grf_offset = 0x104 ,
. supply_names = {
" pmu " ,
} ,
} ;
2022-08-18 18:11:18 +05:30
static const struct rockchip_iodomain_soc_data soc_data_rv1126_pmu = {
. grf_offset = 0x140 ,
. supply_names = {
NULL ,
" vccio1 " ,
" vccio2 " ,
" vccio3 " ,
" vccio4 " ,
" vccio5 " ,
" vccio6 " ,
" vccio7 " ,
" pmuio0 " ,
" pmuio1 " ,
} ,
} ;
2014-09-11 15:48:55 -07:00
static const struct of_device_id rockchip_iodomain_match [ ] = {
2018-05-15 19:48:19 +08:00
{
. compatible = " rockchip,px30-io-voltage-domain " ,
. data = ( void * ) & soc_data_px30
} ,
{
. compatible = " rockchip,px30-pmu-io-voltage-domain " ,
. data = ( void * ) & soc_data_px30_pmu
} ,
2014-09-11 15:48:55 -07:00
{
. compatible = " rockchip,rk3188-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3188
2014-09-11 15:48:55 -07:00
} ,
2017-06-09 17:36:14 +08:00
{
. compatible = " rockchip,rk3228-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3228
2017-06-09 17:36:14 +08:00
} ,
2014-09-11 15:48:55 -07:00
{
. compatible = " rockchip,rk3288-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3288
2014-09-11 15:48:55 -07:00
} ,
2017-02-23 20:33:11 +08:00
{
. compatible = " rockchip,rk3328-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3328
2017-02-23 20:33:11 +08:00
} ,
2015-08-04 21:37:01 +02:00
{
. compatible = " rockchip,rk3368-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3368
2015-08-04 21:37:01 +02:00
} ,
{
. compatible = " rockchip,rk3368-pmu-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3368_pmu
2015-08-04 21:37:01 +02:00
} ,
2016-03-16 02:45:26 +08:00
{
. compatible = " rockchip,rk3399-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3399
2016-03-16 02:45:26 +08:00
} ,
{
. compatible = " rockchip,rk3399-pmu-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rk3399_pmu
2016-03-16 02:45:26 +08:00
} ,
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
{
. compatible = " rockchip,rk3568-pmu-io-voltage-domain " ,
. data = & soc_data_rk3568_pmu
} ,
2017-08-21 18:58:33 +08:00
{
. compatible = " rockchip,rv1108-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rv1108
2017-08-21 18:58:33 +08:00
} ,
{
. compatible = " rockchip,rv1108-pmu-io-voltage-domain " ,
2018-01-02 14:27:57 +01:00
. data = & soc_data_rv1108_pmu
2017-08-21 18:58:33 +08:00
} ,
2022-08-18 18:11:18 +05:30
{
. compatible = " rockchip,rv1126-pmu-io-voltage-domain " ,
. data = & soc_data_rv1126_pmu
} ,
2014-09-11 15:48:55 -07:00
{ /* sentinel */ } ,
} ;
2015-10-02 15:27:57 +01:00
MODULE_DEVICE_TABLE ( of , rockchip_iodomain_match ) ;
2014-09-11 15:48:55 -07:00
static int rockchip_iodomain_probe ( struct platform_device * pdev )
{
struct device_node * np = pdev - > dev . of_node ;
const struct of_device_id * match ;
struct rockchip_iodomain * iod ;
2016-03-31 15:48:42 +02:00
struct device * parent ;
2014-09-11 15:48:55 -07:00
int i , ret = 0 ;
if ( ! np )
return - ENODEV ;
iod = devm_kzalloc ( & pdev - > dev , sizeof ( * iod ) , GFP_KERNEL ) ;
if ( ! iod )
return - ENOMEM ;
iod - > dev = & pdev - > dev ;
platform_set_drvdata ( pdev , iod ) ;
match = of_match_node ( rockchip_iodomain_match , np ) ;
2018-01-02 14:27:57 +01:00
iod - > soc_data = match - > data ;
2014-09-11 15:48:55 -07:00
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
if ( iod - > soc_data - > write )
iod - > write = iod - > soc_data - > write ;
else
iod - > write = rockchip_iodomain_write ;
2016-03-31 15:48:42 +02:00
parent = pdev - > dev . parent ;
if ( parent & & parent - > of_node ) {
iod - > grf = syscon_node_to_regmap ( parent - > of_node ) ;
} else {
dev_dbg ( & pdev - > dev , " falling back to old binding \n " ) ;
iod - > grf = syscon_regmap_lookup_by_phandle ( np , " rockchip,grf " ) ;
}
2014-09-11 15:48:55 -07:00
if ( IS_ERR ( iod - > grf ) ) {
dev_err ( & pdev - > dev , " couldn't find grf regmap \n " ) ;
return PTR_ERR ( iod - > grf ) ;
}
for ( i = 0 ; i < MAX_SUPPLIES ; i + + ) {
const char * supply_name = iod - > soc_data - > supply_names [ i ] ;
struct rockchip_iodomain_supply * supply = & iod - > supplies [ i ] ;
struct regulator * reg ;
int uV ;
if ( ! supply_name )
continue ;
reg = devm_regulator_get_optional ( iod - > dev , supply_name ) ;
if ( IS_ERR ( reg ) ) {
ret = PTR_ERR ( reg ) ;
/* If a supply wasn't specified, that's OK */
if ( ret = = - ENODEV )
continue ;
else if ( ret ! = - EPROBE_DEFER )
dev_err ( iod - > dev , " couldn't get regulator %s \n " ,
supply_name ) ;
goto unreg_notify ;
}
/* set initial correct value */
uV = regulator_get_voltage ( reg ) ;
/* must be a regulator we can get the voltage of */
if ( uV < 0 ) {
dev_err ( iod - > dev , " Can't determine voltage: %s \n " ,
supply_name ) ;
2020-12-04 16:33:25 +08:00
ret = uV ;
2014-09-11 15:48:55 -07:00
goto unreg_notify ;
}
if ( uV > MAX_VOLTAGE_3_3 ) {
dev_crit ( iod - > dev ,
" %d uV is too high. May damage SoC! \n " ,
uV ) ;
ret = - EINVAL ;
goto unreg_notify ;
}
/* setup our supply */
supply - > idx = i ;
supply - > iod = iod ;
supply - > reg = reg ;
supply - > nb . notifier_call = rockchip_iodomain_notify ;
soc: rockchip: io-domain: add rk3568 support
The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.
This patch make the write to be a operation, allow rk3568 uses a private
register set function.
Since the 2.5v mode hasn't been fully validated yet, the driver only sets
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode
There is not register order requirement which has been cleared by our IC
team.
For future reference the full usage matrix including the 2.5V setting is:
case V33 V25 V18 result
0 0 0 0 IO safe, but cannot work
1 0 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
2 0 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
3 0 1 1 Invalid state, should avoid
4 1 0 0 IO require 3.3V, should < 3.63V, otherwise IO may damage
5 1 0 1 IO require 1.8V, should < 1.98V, otherwise IO may damage
6 1 1 0 IO require 2.5V, should < 2.75V, otherwise IO may damage
7 1 1 1 Invalid state, should avoid
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
[added mode clarification from Jay]
Link: https://lore.kernel.org/r/20210805120107.27007-3-michael.riesch@wolfvision.net
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2021-08-05 14:01:02 +02:00
ret = iod - > write ( supply , uV ) ;
2014-09-11 15:48:55 -07:00
if ( ret ) {
supply - > reg = NULL ;
goto unreg_notify ;
}
/* register regulator notifier */
ret = regulator_register_notifier ( reg , & supply - > nb ) ;
if ( ret ) {
dev_err ( & pdev - > dev ,
" regulator notifier request failed \n " ) ;
supply - > reg = NULL ;
goto unreg_notify ;
}
}
if ( iod - > soc_data - > init )
iod - > soc_data - > init ( iod ) ;
return 0 ;
unreg_notify :
for ( i = MAX_SUPPLIES - 1 ; i > = 0 ; i - - ) {
struct rockchip_iodomain_supply * io_supply = & iod - > supplies [ i ] ;
if ( io_supply - > reg )
regulator_unregister_notifier ( io_supply - > reg ,
& io_supply - > nb ) ;
}
return ret ;
}
static int rockchip_iodomain_remove ( struct platform_device * pdev )
{
struct rockchip_iodomain * iod = platform_get_drvdata ( pdev ) ;
int i ;
for ( i = MAX_SUPPLIES - 1 ; i > = 0 ; i - - ) {
struct rockchip_iodomain_supply * io_supply = & iod - > supplies [ i ] ;
if ( io_supply - > reg )
regulator_unregister_notifier ( io_supply - > reg ,
& io_supply - > nb ) ;
}
return 0 ;
}
static struct platform_driver rockchip_iodomain_driver = {
. probe = rockchip_iodomain_probe ,
. remove = rockchip_iodomain_remove ,
. driver = {
. name = " rockchip-iodomain " ,
. of_match_table = rockchip_iodomain_match ,
} ,
} ;
module_platform_driver ( rockchip_iodomain_driver ) ;
MODULE_DESCRIPTION ( " Rockchip IO-domain driver " ) ;
MODULE_AUTHOR ( " Heiko Stuebner <heiko@sntech.de> " ) ;
MODULE_AUTHOR ( " Doug Anderson <dianders@chromium.org> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;