2019-05-27 09:55:21 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2016-01-04 20:36:34 +03:00
/*
* Copyright ( c ) 2015 MediaTek Inc .
*/
# include <linux/clk.h>
2017-03-31 14:30:31 +03:00
# include <linux/iopoll.h>
2016-01-04 20:36:34 +03:00
# include <linux/module.h>
# include <linux/of_device.h>
# include <linux/platform_device.h>
# include <linux/regmap.h>
2020-07-21 06:24:36 +03:00
# include <linux/soc/mediatek/mtk-mmsys.h>
2020-07-21 10:46:06 +03:00
# include <linux/soc/mediatek/mtk-mutex.h>
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
# define MT2701_MUTEX0_MOD0 0x2c
# define MT2701_MUTEX0_SOF0 0x30
2021-01-29 12:22:08 +03:00
# define MT8183_MUTEX0_MOD0 0x30
# define MT8183_MUTEX0_SOF0 0x2c
2019-08-29 17:50:30 +03:00
# define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
# define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
# define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n))
# define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n))
2019-08-29 17:50:32 +03:00
# define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n))
2019-08-29 17:50:30 +03:00
# define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n))
2016-01-04 20:36:34 +03:00
2017-03-31 14:30:31 +03:00
# define INT_MUTEX BIT(1)
2020-10-23 16:31:29 +03:00
# define MT8167_MUTEX_MOD_DISP_PWM 1
# define MT8167_MUTEX_MOD_DISP_OVL0 6
# define MT8167_MUTEX_MOD_DISP_OVL1 7
# define MT8167_MUTEX_MOD_DISP_RDMA0 8
# define MT8167_MUTEX_MOD_DISP_RDMA1 9
# define MT8167_MUTEX_MOD_DISP_WDMA0 10
# define MT8167_MUTEX_MOD_DISP_CCORR 11
# define MT8167_MUTEX_MOD_DISP_COLOR 12
# define MT8167_MUTEX_MOD_DISP_AAL 13
# define MT8167_MUTEX_MOD_DISP_GAMMA 14
# define MT8167_MUTEX_MOD_DISP_DITHER 15
# define MT8167_MUTEX_MOD_DISP_UFOE 16
2021-01-29 12:22:08 +03:00
# define MT8183_MUTEX_MOD_DISP_RDMA0 0
# define MT8183_MUTEX_MOD_DISP_RDMA1 1
# define MT8183_MUTEX_MOD_DISP_OVL0 9
# define MT8183_MUTEX_MOD_DISP_OVL0_2L 10
# define MT8183_MUTEX_MOD_DISP_OVL1_2L 11
# define MT8183_MUTEX_MOD_DISP_WDMA0 12
# define MT8183_MUTEX_MOD_DISP_COLOR0 13
# define MT8183_MUTEX_MOD_DISP_CCORR0 14
# define MT8183_MUTEX_MOD_DISP_AAL0 15
# define MT8183_MUTEX_MOD_DISP_GAMMA0 16
# define MT8183_MUTEX_MOD_DISP_DITHER0 17
2018-06-20 11:19:04 +03:00
# define MT8173_MUTEX_MOD_DISP_OVL0 11
# define MT8173_MUTEX_MOD_DISP_OVL1 12
# define MT8173_MUTEX_MOD_DISP_RDMA0 13
# define MT8173_MUTEX_MOD_DISP_RDMA1 14
# define MT8173_MUTEX_MOD_DISP_RDMA2 15
# define MT8173_MUTEX_MOD_DISP_WDMA0 16
# define MT8173_MUTEX_MOD_DISP_WDMA1 17
# define MT8173_MUTEX_MOD_DISP_COLOR0 18
# define MT8173_MUTEX_MOD_DISP_COLOR1 19
# define MT8173_MUTEX_MOD_DISP_AAL 20
# define MT8173_MUTEX_MOD_DISP_GAMMA 21
# define MT8173_MUTEX_MOD_DISP_UFOE 22
# define MT8173_MUTEX_MOD_DISP_PWM0 23
# define MT8173_MUTEX_MOD_DISP_PWM1 24
# define MT8173_MUTEX_MOD_DISP_OD 25
2018-06-20 11:19:31 +03:00
# define MT2712_MUTEX_MOD_DISP_PWM2 10
# define MT2712_MUTEX_MOD_DISP_OVL0 11
# define MT2712_MUTEX_MOD_DISP_OVL1 12
# define MT2712_MUTEX_MOD_DISP_RDMA0 13
# define MT2712_MUTEX_MOD_DISP_RDMA1 14
# define MT2712_MUTEX_MOD_DISP_RDMA2 15
# define MT2712_MUTEX_MOD_DISP_WDMA0 16
# define MT2712_MUTEX_MOD_DISP_WDMA1 17
# define MT2712_MUTEX_MOD_DISP_COLOR0 18
# define MT2712_MUTEX_MOD_DISP_COLOR1 19
# define MT2712_MUTEX_MOD_DISP_AAL0 20
# define MT2712_MUTEX_MOD_DISP_UFOE 22
# define MT2712_MUTEX_MOD_DISP_PWM0 23
# define MT2712_MUTEX_MOD_DISP_PWM1 24
# define MT2712_MUTEX_MOD_DISP_OD0 25
# define MT2712_MUTEX_MOD2_DISP_AAL1 33
# define MT2712_MUTEX_MOD2_DISP_OD1 34
2018-06-20 11:19:04 +03:00
# define MT2701_MUTEX_MOD_DISP_OVL 3
# define MT2701_MUTEX_MOD_DISP_WDMA 6
# define MT2701_MUTEX_MOD_DISP_COLOR 7
# define MT2701_MUTEX_MOD_DISP_BLS 9
# define MT2701_MUTEX_MOD_DISP_RDMA0 10
# define MT2701_MUTEX_MOD_DISP_RDMA1 12
2017-03-31 14:30:39 +03:00
2020-07-21 06:24:36 +03:00
# define MT2712_MUTEX_SOF_SINGLE_MODE 0
# define MT2712_MUTEX_SOF_DSI0 1
# define MT2712_MUTEX_SOF_DSI1 2
# define MT2712_MUTEX_SOF_DPI0 3
# define MT2712_MUTEX_SOF_DPI1 4
# define MT2712_MUTEX_SOF_DSI2 5
# define MT2712_MUTEX_SOF_DSI3 6
# define MT8167_MUTEX_SOF_DPI0 2
# define MT8167_MUTEX_SOF_DPI1 3
2021-01-29 12:22:08 +03:00
# define MT8183_MUTEX_SOF_DSI0 1
# define MT8183_MUTEX_SOF_DPI0 2
# define MT8183_MUTEX_EOF_DSI0 (MT8183_MUTEX_SOF_DSI0 << 6)
# define MT8183_MUTEX_EOF_DPI0 (MT8183_MUTEX_SOF_DPI0 << 6)
2020-07-21 06:24:36 +03:00
struct mtk_mutex {
2016-01-04 20:36:34 +03:00
int id ;
bool claimed ;
} ;
2020-07-21 06:24:36 +03:00
enum mtk_mutex_sof_id {
MUTEX_SOF_SINGLE_MODE ,
MUTEX_SOF_DSI0 ,
MUTEX_SOF_DSI1 ,
MUTEX_SOF_DPI0 ,
MUTEX_SOF_DPI1 ,
MUTEX_SOF_DSI2 ,
MUTEX_SOF_DSI3 ,
2019-08-29 17:50:31 +03:00
} ;
2020-07-21 06:24:36 +03:00
struct mtk_mutex_data {
2019-08-29 17:50:29 +03:00
const unsigned int * mutex_mod ;
2019-08-29 17:50:31 +03:00
const unsigned int * mutex_sof ;
2019-08-29 17:50:30 +03:00
const unsigned int mutex_mod_reg ;
2019-08-29 17:50:32 +03:00
const unsigned int mutex_sof_reg ;
2019-10-09 11:37:47 +03:00
const bool no_clk ;
2019-08-29 17:50:29 +03:00
} ;
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx {
2016-01-04 20:36:34 +03:00
struct device * dev ;
struct clk * clk ;
void __iomem * regs ;
2020-07-21 06:24:36 +03:00
struct mtk_mutex mutex [ 10 ] ;
const struct mtk_mutex_data * data ;
2016-01-04 20:36:34 +03:00
} ;
2017-03-31 14:30:39 +03:00
static const unsigned int mt2701_mutex_mod [ DDP_COMPONENT_ID_MAX ] = {
[ DDP_COMPONENT_BLS ] = MT2701_MUTEX_MOD_DISP_BLS ,
[ DDP_COMPONENT_COLOR0 ] = MT2701_MUTEX_MOD_DISP_COLOR ,
[ DDP_COMPONENT_OVL0 ] = MT2701_MUTEX_MOD_DISP_OVL ,
[ DDP_COMPONENT_RDMA0 ] = MT2701_MUTEX_MOD_DISP_RDMA0 ,
[ DDP_COMPONENT_RDMA1 ] = MT2701_MUTEX_MOD_DISP_RDMA1 ,
[ DDP_COMPONENT_WDMA0 ] = MT2701_MUTEX_MOD_DISP_WDMA ,
} ;
2018-06-20 11:19:31 +03:00
static const unsigned int mt2712_mutex_mod [ DDP_COMPONENT_ID_MAX ] = {
[ DDP_COMPONENT_AAL0 ] = MT2712_MUTEX_MOD_DISP_AAL0 ,
[ DDP_COMPONENT_AAL1 ] = MT2712_MUTEX_MOD2_DISP_AAL1 ,
[ DDP_COMPONENT_COLOR0 ] = MT2712_MUTEX_MOD_DISP_COLOR0 ,
[ DDP_COMPONENT_COLOR1 ] = MT2712_MUTEX_MOD_DISP_COLOR1 ,
[ DDP_COMPONENT_OD0 ] = MT2712_MUTEX_MOD_DISP_OD0 ,
[ DDP_COMPONENT_OD1 ] = MT2712_MUTEX_MOD2_DISP_OD1 ,
[ DDP_COMPONENT_OVL0 ] = MT2712_MUTEX_MOD_DISP_OVL0 ,
[ DDP_COMPONENT_OVL1 ] = MT2712_MUTEX_MOD_DISP_OVL1 ,
[ DDP_COMPONENT_PWM0 ] = MT2712_MUTEX_MOD_DISP_PWM0 ,
[ DDP_COMPONENT_PWM1 ] = MT2712_MUTEX_MOD_DISP_PWM1 ,
[ DDP_COMPONENT_PWM2 ] = MT2712_MUTEX_MOD_DISP_PWM2 ,
[ DDP_COMPONENT_RDMA0 ] = MT2712_MUTEX_MOD_DISP_RDMA0 ,
[ DDP_COMPONENT_RDMA1 ] = MT2712_MUTEX_MOD_DISP_RDMA1 ,
[ DDP_COMPONENT_RDMA2 ] = MT2712_MUTEX_MOD_DISP_RDMA2 ,
[ DDP_COMPONENT_UFOE ] = MT2712_MUTEX_MOD_DISP_UFOE ,
[ DDP_COMPONENT_WDMA0 ] = MT2712_MUTEX_MOD_DISP_WDMA0 ,
[ DDP_COMPONENT_WDMA1 ] = MT2712_MUTEX_MOD_DISP_WDMA1 ,
} ;
2020-10-23 16:31:29 +03:00
static const unsigned int mt8167_mutex_mod [ DDP_COMPONENT_ID_MAX ] = {
[ DDP_COMPONENT_AAL0 ] = MT8167_MUTEX_MOD_DISP_AAL ,
[ DDP_COMPONENT_CCORR ] = MT8167_MUTEX_MOD_DISP_CCORR ,
[ DDP_COMPONENT_COLOR0 ] = MT8167_MUTEX_MOD_DISP_COLOR ,
[ DDP_COMPONENT_DITHER ] = MT8167_MUTEX_MOD_DISP_DITHER ,
[ DDP_COMPONENT_GAMMA ] = MT8167_MUTEX_MOD_DISP_GAMMA ,
[ DDP_COMPONENT_OVL0 ] = MT8167_MUTEX_MOD_DISP_OVL0 ,
[ DDP_COMPONENT_OVL1 ] = MT8167_MUTEX_MOD_DISP_OVL1 ,
[ DDP_COMPONENT_PWM0 ] = MT8167_MUTEX_MOD_DISP_PWM ,
[ DDP_COMPONENT_RDMA0 ] = MT8167_MUTEX_MOD_DISP_RDMA0 ,
[ DDP_COMPONENT_RDMA1 ] = MT8167_MUTEX_MOD_DISP_RDMA1 ,
[ DDP_COMPONENT_UFOE ] = MT8167_MUTEX_MOD_DISP_UFOE ,
[ DDP_COMPONENT_WDMA0 ] = MT8167_MUTEX_MOD_DISP_WDMA0 ,
} ;
2017-03-31 14:30:30 +03:00
static const unsigned int mt8173_mutex_mod [ DDP_COMPONENT_ID_MAX ] = {
2018-06-20 11:19:05 +03:00
[ DDP_COMPONENT_AAL0 ] = MT8173_MUTEX_MOD_DISP_AAL ,
2017-03-31 14:30:30 +03:00
[ DDP_COMPONENT_COLOR0 ] = MT8173_MUTEX_MOD_DISP_COLOR0 ,
[ DDP_COMPONENT_COLOR1 ] = MT8173_MUTEX_MOD_DISP_COLOR1 ,
[ DDP_COMPONENT_GAMMA ] = MT8173_MUTEX_MOD_DISP_GAMMA ,
2018-06-20 11:19:06 +03:00
[ DDP_COMPONENT_OD0 ] = MT8173_MUTEX_MOD_DISP_OD ,
2017-03-31 14:30:30 +03:00
[ DDP_COMPONENT_OVL0 ] = MT8173_MUTEX_MOD_DISP_OVL0 ,
[ DDP_COMPONENT_OVL1 ] = MT8173_MUTEX_MOD_DISP_OVL1 ,
[ DDP_COMPONENT_PWM0 ] = MT8173_MUTEX_MOD_DISP_PWM0 ,
[ DDP_COMPONENT_PWM1 ] = MT8173_MUTEX_MOD_DISP_PWM1 ,
[ DDP_COMPONENT_RDMA0 ] = MT8173_MUTEX_MOD_DISP_RDMA0 ,
[ DDP_COMPONENT_RDMA1 ] = MT8173_MUTEX_MOD_DISP_RDMA1 ,
[ DDP_COMPONENT_RDMA2 ] = MT8173_MUTEX_MOD_DISP_RDMA2 ,
[ DDP_COMPONENT_UFOE ] = MT8173_MUTEX_MOD_DISP_UFOE ,
[ DDP_COMPONENT_WDMA0 ] = MT8173_MUTEX_MOD_DISP_WDMA0 ,
[ DDP_COMPONENT_WDMA1 ] = MT8173_MUTEX_MOD_DISP_WDMA1 ,
2016-01-04 20:36:34 +03:00
} ;
2021-01-29 12:22:08 +03:00
static const unsigned int mt8183_mutex_mod [ DDP_COMPONENT_ID_MAX ] = {
[ DDP_COMPONENT_AAL0 ] = MT8183_MUTEX_MOD_DISP_AAL0 ,
[ DDP_COMPONENT_CCORR ] = MT8183_MUTEX_MOD_DISP_CCORR0 ,
[ DDP_COMPONENT_COLOR0 ] = MT8183_MUTEX_MOD_DISP_COLOR0 ,
[ DDP_COMPONENT_DITHER ] = MT8183_MUTEX_MOD_DISP_DITHER0 ,
[ DDP_COMPONENT_GAMMA ] = MT8183_MUTEX_MOD_DISP_GAMMA0 ,
[ DDP_COMPONENT_OVL0 ] = MT8183_MUTEX_MOD_DISP_OVL0 ,
[ DDP_COMPONENT_OVL_2L0 ] = MT8183_MUTEX_MOD_DISP_OVL0_2L ,
[ DDP_COMPONENT_OVL_2L1 ] = MT8183_MUTEX_MOD_DISP_OVL1_2L ,
[ DDP_COMPONENT_RDMA0 ] = MT8183_MUTEX_MOD_DISP_RDMA0 ,
[ DDP_COMPONENT_RDMA1 ] = MT8183_MUTEX_MOD_DISP_RDMA1 ,
[ DDP_COMPONENT_WDMA0 ] = MT8183_MUTEX_MOD_DISP_WDMA0 ,
} ;
2020-07-21 06:24:36 +03:00
static const unsigned int mt2712_mutex_sof [ MUTEX_SOF_DSI3 + 1 ] = {
[ MUTEX_SOF_SINGLE_MODE ] = MUTEX_SOF_SINGLE_MODE ,
[ MUTEX_SOF_DSI0 ] = MUTEX_SOF_DSI0 ,
[ MUTEX_SOF_DSI1 ] = MUTEX_SOF_DSI1 ,
[ MUTEX_SOF_DPI0 ] = MUTEX_SOF_DPI0 ,
[ MUTEX_SOF_DPI1 ] = MUTEX_SOF_DPI1 ,
[ MUTEX_SOF_DSI2 ] = MUTEX_SOF_DSI2 ,
[ MUTEX_SOF_DSI3 ] = MUTEX_SOF_DSI3 ,
2019-08-29 17:50:31 +03:00
} ;
2020-07-21 06:24:36 +03:00
static const unsigned int mt8167_mutex_sof [ MUTEX_SOF_DSI3 + 1 ] = {
[ MUTEX_SOF_SINGLE_MODE ] = MUTEX_SOF_SINGLE_MODE ,
[ MUTEX_SOF_DSI0 ] = MUTEX_SOF_DSI0 ,
[ MUTEX_SOF_DPI0 ] = MT8167_MUTEX_SOF_DPI0 ,
[ MUTEX_SOF_DPI1 ] = MT8167_MUTEX_SOF_DPI1 ,
2020-10-23 16:31:29 +03:00
} ;
2021-01-29 12:22:08 +03:00
/* Add EOF setting so overlay hardware can receive frame done irq */
static const unsigned int mt8183_mutex_sof [ MUTEX_SOF_DSI3 + 1 ] = {
[ MUTEX_SOF_SINGLE_MODE ] = MUTEX_SOF_SINGLE_MODE ,
[ MUTEX_SOF_DSI0 ] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0 ,
[ MUTEX_SOF_DPI0 ] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0 ,
} ;
2020-07-21 06:24:36 +03:00
static const struct mtk_mutex_data mt2701_mutex_driver_data = {
2019-08-29 17:50:29 +03:00
. mutex_mod = mt2701_mutex_mod ,
2019-08-29 17:50:31 +03:00
. mutex_sof = mt2712_mutex_sof ,
2020-07-21 06:24:36 +03:00
. mutex_mod_reg = MT2701_MUTEX0_MOD0 ,
. mutex_sof_reg = MT2701_MUTEX0_SOF0 ,
2019-08-29 17:50:29 +03:00
} ;
2020-07-21 06:24:36 +03:00
static const struct mtk_mutex_data mt2712_mutex_driver_data = {
2019-08-29 17:50:29 +03:00
. mutex_mod = mt2712_mutex_mod ,
2019-08-29 17:50:31 +03:00
. mutex_sof = mt2712_mutex_sof ,
2020-07-21 06:24:36 +03:00
. mutex_mod_reg = MT2701_MUTEX0_MOD0 ,
. mutex_sof_reg = MT2701_MUTEX0_SOF0 ,
2019-08-29 17:50:29 +03:00
} ;
2020-07-21 06:24:36 +03:00
static const struct mtk_mutex_data mt8167_mutex_driver_data = {
2020-10-23 16:31:29 +03:00
. mutex_mod = mt8167_mutex_mod ,
. mutex_sof = mt8167_mutex_sof ,
2020-07-21 06:24:36 +03:00
. mutex_mod_reg = MT2701_MUTEX0_MOD0 ,
. mutex_sof_reg = MT2701_MUTEX0_SOF0 ,
2020-10-23 16:31:29 +03:00
. no_clk = true ,
} ;
2020-07-21 06:24:36 +03:00
static const struct mtk_mutex_data mt8173_mutex_driver_data = {
2019-08-29 17:50:29 +03:00
. mutex_mod = mt8173_mutex_mod ,
2019-08-29 17:50:31 +03:00
. mutex_sof = mt2712_mutex_sof ,
2020-07-21 06:24:36 +03:00
. mutex_mod_reg = MT2701_MUTEX0_MOD0 ,
. mutex_sof_reg = MT2701_MUTEX0_SOF0 ,
2019-08-29 17:50:29 +03:00
} ;
2021-01-29 12:22:08 +03:00
static const struct mtk_mutex_data mt8183_mutex_driver_data = {
. mutex_mod = mt8183_mutex_mod ,
. mutex_sof = mt8183_mutex_sof ,
. mutex_mod_reg = MT8183_MUTEX0_MOD0 ,
. mutex_sof_reg = MT8183_MUTEX0_SOF0 ,
. no_clk = true ,
} ;
2020-07-21 06:30:11 +03:00
struct mtk_mutex * mtk_mutex_get ( struct device * dev )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = dev_get_drvdata ( dev ) ;
2020-07-21 06:30:11 +03:00
int i ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:30:11 +03:00
for ( i = 0 ; i < 10 ; i + + )
if ( ! mtx - > mutex [ i ] . claimed ) {
mtx - > mutex [ i ] . claimed = true ;
return & mtx - > mutex [ i ] ;
}
2016-01-04 20:36:34 +03:00
2020-07-21 06:30:11 +03:00
return ERR_PTR ( - EBUSY ) ;
2016-01-04 20:36:34 +03:00
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_get ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_put ( struct mtk_mutex * mutex )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
WARN_ON ( & mtx - > mutex [ mutex - > id ] ! = mutex ) ;
2016-01-04 20:36:34 +03:00
mutex - > claimed = false ;
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_put ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
int mtk_mutex_prepare ( struct mtk_mutex * mutex )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
return clk_prepare_enable ( mtx - > clk ) ;
2016-01-04 20:36:34 +03:00
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_prepare ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_unprepare ( struct mtk_mutex * mutex )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
clk_disable_unprepare ( mtx - > clk ) ;
2016-01-04 20:36:34 +03:00
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_unprepare ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_add_comp ( struct mtk_mutex * mutex ,
enum mtk_ddp_comp_id id )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
2016-01-04 20:36:34 +03:00
unsigned int reg ;
2019-08-29 17:50:31 +03:00
unsigned int sof_id ;
2018-06-20 11:19:04 +03:00
unsigned int offset ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
WARN_ON ( & mtx - > mutex [ mutex - > id ] ! = mutex ) ;
2016-01-04 20:36:34 +03:00
switch ( id ) {
case DDP_COMPONENT_DSI0 :
2020-07-21 06:24:36 +03:00
sof_id = MUTEX_SOF_DSI0 ;
2016-01-04 20:36:34 +03:00
break ;
case DDP_COMPONENT_DSI1 :
2020-07-21 06:24:36 +03:00
sof_id = MUTEX_SOF_DSI0 ;
2016-01-04 20:36:34 +03:00
break ;
2018-06-20 11:19:28 +03:00
case DDP_COMPONENT_DSI2 :
2020-07-21 06:24:36 +03:00
sof_id = MUTEX_SOF_DSI2 ;
2018-06-20 11:19:28 +03:00
break ;
2018-06-20 11:19:29 +03:00
case DDP_COMPONENT_DSI3 :
2020-07-21 06:24:36 +03:00
sof_id = MUTEX_SOF_DSI3 ;
2018-06-20 11:19:29 +03:00
break ;
2016-01-04 20:36:34 +03:00
case DDP_COMPONENT_DPI0 :
2020-07-21 06:24:36 +03:00
sof_id = MUTEX_SOF_DPI0 ;
2016-01-04 20:36:34 +03:00
break ;
2018-06-20 11:19:27 +03:00
case DDP_COMPONENT_DPI1 :
2020-07-21 06:24:36 +03:00
sof_id = MUTEX_SOF_DPI1 ;
2018-06-20 11:19:27 +03:00
break ;
2016-01-04 20:36:34 +03:00
default :
2020-07-21 06:24:36 +03:00
if ( mtx - > data - > mutex_mod [ id ] < 32 ) {
offset = DISP_REG_MUTEX_MOD ( mtx - > data - > mutex_mod_reg ,
2019-08-29 17:50:30 +03:00
mutex - > id ) ;
2020-07-21 06:24:36 +03:00
reg = readl_relaxed ( mtx - > regs + offset ) ;
reg | = 1 < < mtx - > data - > mutex_mod [ id ] ;
writel_relaxed ( reg , mtx - > regs + offset ) ;
2018-06-20 11:19:04 +03:00
} else {
offset = DISP_REG_MUTEX_MOD2 ( mutex - > id ) ;
2020-07-21 06:24:36 +03:00
reg = readl_relaxed ( mtx - > regs + offset ) ;
reg | = 1 < < ( mtx - > data - > mutex_mod [ id ] - 32 ) ;
writel_relaxed ( reg , mtx - > regs + offset ) ;
2018-06-20 11:19:04 +03:00
}
2016-01-04 20:36:34 +03:00
return ;
}
2020-07-21 06:24:36 +03:00
writel_relaxed ( mtx - > data - > mutex_sof [ sof_id ] ,
mtx - > regs +
DISP_REG_MUTEX_SOF ( mtx - > data - > mutex_sof_reg , mutex - > id ) ) ;
2016-01-04 20:36:34 +03:00
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_add_comp ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_remove_comp ( struct mtk_mutex * mutex ,
enum mtk_ddp_comp_id id )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
2016-01-04 20:36:34 +03:00
unsigned int reg ;
2018-06-20 11:19:04 +03:00
unsigned int offset ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
WARN_ON ( & mtx - > mutex [ mutex - > id ] ! = mutex ) ;
2016-01-04 20:36:34 +03:00
switch ( id ) {
case DDP_COMPONENT_DSI0 :
case DDP_COMPONENT_DSI1 :
2018-06-20 11:19:28 +03:00
case DDP_COMPONENT_DSI2 :
2018-06-20 11:19:29 +03:00
case DDP_COMPONENT_DSI3 :
2016-01-04 20:36:34 +03:00
case DDP_COMPONENT_DPI0 :
2018-06-20 11:19:27 +03:00
case DDP_COMPONENT_DPI1 :
2016-01-04 20:36:34 +03:00
writel_relaxed ( MUTEX_SOF_SINGLE_MODE ,
2020-07-21 06:24:36 +03:00
mtx - > regs +
DISP_REG_MUTEX_SOF ( mtx - > data - > mutex_sof_reg ,
2019-08-29 17:50:32 +03:00
mutex - > id ) ) ;
2016-01-04 20:36:34 +03:00
break ;
default :
2020-07-21 06:24:36 +03:00
if ( mtx - > data - > mutex_mod [ id ] < 32 ) {
offset = DISP_REG_MUTEX_MOD ( mtx - > data - > mutex_mod_reg ,
2019-08-29 17:50:30 +03:00
mutex - > id ) ;
2020-07-21 06:24:36 +03:00
reg = readl_relaxed ( mtx - > regs + offset ) ;
reg & = ~ ( 1 < < mtx - > data - > mutex_mod [ id ] ) ;
writel_relaxed ( reg , mtx - > regs + offset ) ;
2018-06-20 11:19:04 +03:00
} else {
offset = DISP_REG_MUTEX_MOD2 ( mutex - > id ) ;
2020-07-21 06:24:36 +03:00
reg = readl_relaxed ( mtx - > regs + offset ) ;
reg & = ~ ( 1 < < ( mtx - > data - > mutex_mod [ id ] - 32 ) ) ;
writel_relaxed ( reg , mtx - > regs + offset ) ;
2018-06-20 11:19:04 +03:00
}
2016-01-04 20:36:34 +03:00
break ;
}
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_remove_comp ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_enable ( struct mtk_mutex * mutex )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
WARN_ON ( & mtx - > mutex [ mutex - > id ] ! = mutex ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
writel ( 1 , mtx - > regs + DISP_REG_MUTEX_EN ( mutex - > id ) ) ;
2016-01-04 20:36:34 +03:00
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_enable ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_disable ( struct mtk_mutex * mutex )
2016-01-04 20:36:34 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
WARN_ON ( & mtx - > mutex [ mutex - > id ] ! = mutex ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
writel ( 0 , mtx - > regs + DISP_REG_MUTEX_EN ( mutex - > id ) ) ;
2016-01-04 20:36:34 +03:00
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_disable ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_acquire ( struct mtk_mutex * mutex )
2017-03-31 14:30:31 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
2017-03-31 14:30:31 +03:00
u32 tmp ;
2020-07-21 06:24:36 +03:00
writel ( 1 , mtx - > regs + DISP_REG_MUTEX_EN ( mutex - > id ) ) ;
writel ( 1 , mtx - > regs + DISP_REG_MUTEX ( mutex - > id ) ) ;
if ( readl_poll_timeout_atomic ( mtx - > regs + DISP_REG_MUTEX ( mutex - > id ) ,
2017-03-31 14:30:31 +03:00
tmp , tmp & INT_MUTEX , 1 , 10000 ) )
pr_err ( " could not acquire mutex %d \n " , mutex - > id ) ;
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_acquire ) ;
2017-03-31 14:30:31 +03:00
2020-07-21 06:24:36 +03:00
void mtk_mutex_release ( struct mtk_mutex * mutex )
2017-03-31 14:30:31 +03:00
{
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx = container_of ( mutex , struct mtk_mutex_ctx ,
mutex [ mutex - > id ] ) ;
2017-03-31 14:30:31 +03:00
2020-07-21 06:24:36 +03:00
writel ( 0 , mtx - > regs + DISP_REG_MUTEX ( mutex - > id ) ) ;
2017-03-31 14:30:31 +03:00
}
2020-07-21 10:46:06 +03:00
EXPORT_SYMBOL_GPL ( mtk_mutex_release ) ;
2017-03-31 14:30:31 +03:00
2020-07-21 06:24:36 +03:00
static int mtk_mutex_probe ( struct platform_device * pdev )
2016-01-04 20:36:34 +03:00
{
struct device * dev = & pdev - > dev ;
2020-07-21 06:24:36 +03:00
struct mtk_mutex_ctx * mtx ;
2016-01-04 20:36:34 +03:00
struct resource * regs ;
int i ;
2020-07-21 06:24:36 +03:00
mtx = devm_kzalloc ( dev , sizeof ( * mtx ) , GFP_KERNEL ) ;
if ( ! mtx )
2016-01-04 20:36:34 +03:00
return - ENOMEM ;
for ( i = 0 ; i < 10 ; i + + )
2020-07-21 06:24:36 +03:00
mtx - > mutex [ i ] . id = i ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
mtx - > data = of_device_get_match_data ( dev ) ;
2019-10-09 11:37:47 +03:00
2020-07-21 06:24:36 +03:00
if ( ! mtx - > data - > no_clk ) {
mtx - > clk = devm_clk_get ( dev , NULL ) ;
if ( IS_ERR ( mtx - > clk ) ) {
if ( PTR_ERR ( mtx - > clk ) ! = - EPROBE_DEFER )
2020-03-25 20:31:19 +03:00
dev_err ( dev , " Failed to get clock \n " ) ;
2020-07-21 06:24:36 +03:00
return PTR_ERR ( mtx - > clk ) ;
2019-10-09 11:37:47 +03:00
}
2016-01-04 20:36:34 +03:00
}
regs = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2020-07-21 06:24:36 +03:00
mtx - > regs = devm_ioremap_resource ( dev , regs ) ;
if ( IS_ERR ( mtx - > regs ) ) {
2016-01-04 20:36:34 +03:00
dev_err ( dev , " Failed to map mutex registers \n " ) ;
2020-07-21 06:24:36 +03:00
return PTR_ERR ( mtx - > regs ) ;
2016-01-04 20:36:34 +03:00
}
2020-07-21 06:24:36 +03:00
platform_set_drvdata ( pdev , mtx ) ;
2016-01-04 20:36:34 +03:00
return 0 ;
}
2020-07-21 06:24:36 +03:00
static int mtk_mutex_remove ( struct platform_device * pdev )
2016-01-04 20:36:34 +03:00
{
return 0 ;
}
2020-07-21 06:24:36 +03:00
static const struct of_device_id mutex_driver_dt_match [ ] = {
2019-08-29 17:50:29 +03:00
{ . compatible = " mediatek,mt2701-disp-mutex " ,
2020-07-21 06:24:36 +03:00
. data = & mt2701_mutex_driver_data } ,
2019-08-29 17:50:29 +03:00
{ . compatible = " mediatek,mt2712-disp-mutex " ,
2020-07-21 06:24:36 +03:00
. data = & mt2712_mutex_driver_data } ,
2020-10-23 16:31:29 +03:00
{ . compatible = " mediatek,mt8167-disp-mutex " ,
2020-07-21 06:24:36 +03:00
. data = & mt8167_mutex_driver_data } ,
2019-08-29 17:50:29 +03:00
{ . compatible = " mediatek,mt8173-disp-mutex " ,
2020-07-21 06:24:36 +03:00
. data = & mt8173_mutex_driver_data } ,
2021-01-29 12:22:08 +03:00
{ . compatible = " mediatek,mt8183-disp-mutex " ,
. data = & mt8183_mutex_driver_data } ,
2016-01-04 20:36:34 +03:00
{ } ,
} ;
2020-07-21 06:24:36 +03:00
MODULE_DEVICE_TABLE ( of , mutex_driver_dt_match ) ;
2016-01-04 20:36:34 +03:00
2020-07-21 06:24:36 +03:00
struct platform_driver mtk_mutex_driver = {
. probe = mtk_mutex_probe ,
. remove = mtk_mutex_remove ,
2016-01-04 20:36:34 +03:00
. driver = {
2020-07-21 06:24:36 +03:00
. name = " mediatek-mutex " ,
2016-01-04 20:36:34 +03:00
. owner = THIS_MODULE ,
2020-07-21 06:24:36 +03:00
. of_match_table = mutex_driver_dt_match ,
2016-01-04 20:36:34 +03:00
} ,
} ;
2020-07-21 10:46:06 +03:00
builtin_platform_driver ( mtk_mutex_driver ) ;