summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/sirf
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/sirf')
-rw-r--r--drivers/pinctrl/sirf/pinctrl-atlas7.c193
1 files changed, 94 insertions, 99 deletions
diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c
index d16e62996e05..9df0c5f25824 100644
--- a/drivers/pinctrl/sirf/pinctrl-atlas7.c
+++ b/drivers/pinctrl/sirf/pinctrl-atlas7.c
@@ -3510,11 +3510,19 @@ struct atlas7_pinctrl_data atlas7_ioc_data = {
3510 .confs_cnt = ARRAY_SIZE(atlas7_ioc_pad_confs), 3510 .confs_cnt = ARRAY_SIZE(atlas7_ioc_pad_confs),
3511}; 3511};
3512 3512
3513/* Simple map data structure */
3513struct map_data { 3514struct map_data {
3514 u8 idx; 3515 u8 idx;
3515 u8 data; 3516 u8 data;
3516}; 3517};
3517 3518
3519/**
3520 * struct atlas7_pull_info - Atlas7 Pad pull info
3521 * @type:The type of this Pad.
3522 * @mask:The mas value of this pin's pull bits.
3523 * @v2s: The map of pull register value to pull status.
3524 * @s2v: The map of pull status to pull register value.
3525 */
3518struct atlas7_pull_info { 3526struct atlas7_pull_info {
3519 u8 pad_type; 3527 u8 pad_type;
3520 u8 mask; 3528 u8 mask;
@@ -3597,6 +3605,65 @@ static const struct atlas7_pull_info atlas7_pull_map[] = {
3597 { PAD_T_AD, PANGD_PULL_MASK, pangd_pull_v2s, pangd_pull_s2v }, 3605 { PAD_T_AD, PANGD_PULL_MASK, pangd_pull_v2s, pangd_pull_s2v },
3598}; 3606};
3599 3607
3608/**
3609 * struct atlas7_ds_ma_info - Atlas7 Pad DriveStrength & currents info
3610 * @ma: The Drive Strength in current value .
3611 * @ds_16st: The correspond raw value of 16st pad.
3612 * @ds_4we: The correspond raw value of 4we pad.
3613 * @ds_0204m31: The correspond raw value of 0204m31 pad.
3614 * @ds_0610m31: The correspond raw value of 0610m31 pad.
3615 */
3616struct atlas7_ds_ma_info {
3617 u32 ma;
3618 u32 ds_16st;
3619 u32 ds_4we;
3620 u32 ds_0204m31;
3621 u32 ds_0610m31;
3622};
3623
3624static const struct atlas7_ds_ma_info atlas7_ma2ds_map[] = {
3625 { 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL },
3626 { 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL },
3627 { 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0 },
3628 { 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL },
3629 { 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1 },
3630 { 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL },
3631 { 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL },
3632 { 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL },
3633 { 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL },
3634 { 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL },
3635 { 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL },
3636 { 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL },
3637 { 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL },
3638 { 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL },
3639 { 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL },
3640 { 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL },
3641};
3642
3643/**
3644 * struct atlas7_ds_info - Atlas7 Pad DriveStrength info
3645 * @type: The type of this Pad.
3646 * @mask: The mask value of this pin's pull bits.
3647 * @imval: The immediate value of drives trength register.
3648 */
3649struct atlas7_ds_info {
3650 u8 type;
3651 u8 mask;
3652 u8 imval;
3653 u8 reserved;
3654};
3655
3656static const struct atlas7_ds_info atlas7_ds_map[] = {
3657 { PAD_T_4WE_PD, DS_2BIT_MASK, DS_2BIT_IM_VAL },
3658 { PAD_T_4WE_PU, DS_2BIT_MASK, DS_2BIT_IM_VAL },
3659 { PAD_T_16ST, DS_4BIT_MASK, DS_4BIT_IM_VAL },
3660 { PAD_T_M31_0204_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3661 { PAD_T_M31_0204_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3662 { PAD_T_M31_0610_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3663 { PAD_T_M31_0610_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3664 { PAD_T_AD, DS_NULL, DS_NULL },
3665};
3666
3600static inline u32 atlas7_pin_to_bank(u32 pin) 3667static inline u32 atlas7_pin_to_bank(u32 pin)
3601{ 3668{
3602 return (pin >= ATLAS7_PINCTRL_BANK_0_PINS) ? 1 : 0; 3669 return (pin >= ATLAS7_PINCTRL_BANK_0_PINS) ? 1 : 0;
@@ -3799,70 +3866,27 @@ static int atlas7_pmx_set_mux(struct pinctrl_dev *pctldev,
3799 return 0; 3866 return 0;
3800} 3867}
3801 3868
3802struct atlas7_ds_info {
3803 u32 ma;
3804 u32 ds_16st;
3805 u32 ds_4we;
3806 u32 ds_0204m31;
3807 u32 ds_0610m31;
3808};
3809
3810const struct atlas7_ds_info atlas7_ds_map[] = {
3811 { 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL},
3812 { 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL},
3813 { 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0},
3814 { 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL},
3815 { 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1},
3816 { 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL},
3817 { 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL},
3818 { 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL},
3819 { 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL},
3820 { 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL},
3821 { 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL},
3822 { 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL},
3823 { 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL},
3824 { 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL},
3825 { 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL},
3826 { 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL},
3827};
3828
3829static u32 convert_current_to_drive_strength(u32 type, u32 ma) 3869static u32 convert_current_to_drive_strength(u32 type, u32 ma)
3830{ 3870{
3831 int idx; 3871 int idx;
3832 3872
3833 for (idx = 0; idx < ARRAY_SIZE(atlas7_ds_map); idx++) { 3873 for (idx = 0; idx < ARRAY_SIZE(atlas7_ma2ds_map); idx++) {
3834 if (atlas7_ds_map[idx].ma != ma) 3874 if (atlas7_ma2ds_map[idx].ma != ma)
3835 continue; 3875 continue;
3836 3876
3837 if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU) 3877 if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU)
3838 return atlas7_ds_map[idx].ds_4we; 3878 return atlas7_ma2ds_map[idx].ds_4we;
3839 else if (type == PAD_T_16ST) 3879 else if (type == PAD_T_16ST)
3840 return atlas7_ds_map[idx].ds_16st; 3880 return atlas7_ma2ds_map[idx].ds_16st;
3841 else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU) 3881 else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU)
3842 return atlas7_ds_map[idx].ds_0204m31; 3882 return atlas7_ma2ds_map[idx].ds_0204m31;
3843 else if (type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU) 3883 else if (type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU)
3844 return atlas7_ds_map[idx].ds_0610m31; 3884 return atlas7_ma2ds_map[idx].ds_0610m31;
3845 } 3885 }
3846 3886
3847 return DS_NULL; 3887 return DS_NULL;
3848} 3888}
3849 3889
3850static u32 altas7_pinctrl_get_pull_sel(struct atlas7_pmx *pmx, u32 pin)
3851{
3852 struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin];
3853 const struct atlas7_pull_info *pull_info;
3854 int bank;
3855 unsigned long regv;
3856
3857 bank = atlas7_pin_to_bank(pin);
3858 pull_info = &atlas7_pull_map[conf->type];
3859
3860 regv = readl(pmx->regs[bank] + conf->pupd_reg);
3861 regv = (regv >> conf->pupd_bit) & pull_info->mask;
3862
3863 return pull_info->v2s[regv].data;
3864}
3865
3866static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev, 3890static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev,
3867 u32 pin, u32 sel) 3891 u32 pin, u32 sel)
3868{ 3892{
@@ -3871,19 +3895,17 @@ static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev,
3871 const struct atlas7_pull_info *pull_info; 3895 const struct atlas7_pull_info *pull_info;
3872 u32 bank; 3896 u32 bank;
3873 unsigned long regv; 3897 unsigned long regv;
3874 void __iomem *pull_sel_reg, *pull_clr_reg; 3898 void __iomem *pull_sel_reg;
3875 3899
3876 bank = atlas7_pin_to_bank(pin); 3900 bank = atlas7_pin_to_bank(pin);
3877 pull_info = &atlas7_pull_map[conf->type]; 3901 pull_info = &atlas7_pull_map[conf->type];
3878
3879 pull_sel_reg = pmx->regs[bank] + conf->pupd_reg; 3902 pull_sel_reg = pmx->regs[bank] + conf->pupd_reg;
3880 pull_clr_reg = CLR_REG(pull_sel_reg);
3881 3903
3882 /* Retrieve correspond register value from table by sel */ 3904 /* Retrieve correspond register value from table by sel */
3883 regv = pull_info->s2v[sel].data & pull_info->mask; 3905 regv = pull_info->s2v[sel].data & pull_info->mask;
3884 3906
3885 /* Clear & Set new value to pull register */ 3907 /* Clear & Set new value to pull register */
3886 writel(pull_info->mask << conf->pupd_bit, pull_clr_reg); 3908 writel(pull_info->mask << conf->pupd_bit, CLR_REG(pull_sel_reg));
3887 writel(regv << conf->pupd_bit, pull_sel_reg); 3909 writel(regv << conf->pupd_bit, pull_sel_reg);
3888 3910
3889 pr_debug("PIN_CFG ### SET PIN#%d PULL SELECTOR:%d == OK ####\n", 3911 pr_debug("PIN_CFG ### SET PIN#%d PULL SELECTOR:%d == OK ####\n",
@@ -3896,43 +3918,25 @@ static int __altas7_pinctrl_set_drive_strength_sel(struct pinctrl_dev *pctldev,
3896{ 3918{
3897 struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 3919 struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
3898 struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; 3920 struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin];
3899 u32 type = conf->type; 3921 const struct atlas7_ds_info *ds_info;
3900 u32 shift = conf->drvstr_bit; 3922 u32 bank;
3901 u32 bank = atlas7_pin_to_bank(pin); 3923 void __iomem *ds_sel_reg;
3902 void __iomem *ds_sel_reg, *ds_clr_reg;
3903
3904 ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg;
3905 ds_clr_reg = CLR_REG(ds_sel_reg);
3906 if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU) {
3907 if (sel & (~DS_2BIT_MASK))
3908 goto unsupport;
3909
3910 writel(DS_2BIT_IM_VAL << shift, ds_clr_reg);
3911 writel(sel << shift, ds_sel_reg);
3912
3913 return 0;
3914 } else if (type == PAD_T_16ST) {
3915 if (sel & (~DS_4BIT_MASK))
3916 goto unsupport;
3917 3924
3918 writel(DS_4BIT_IM_VAL << shift, ds_clr_reg); 3925 ds_info = &atlas7_ds_map[conf->type];
3919 writel(sel << shift, ds_sel_reg); 3926 if (sel & (~(ds_info->mask)))
3927 goto unsupport;
3920 3928
3921 return 0; 3929 bank = atlas7_pin_to_bank(pin);
3922 } else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU || 3930 ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg;
3923 type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU) {
3924 if (sel & (~DS_1BIT_MASK))
3925 goto unsupport;
3926 3931
3927 writel(DS_1BIT_IM_VAL << shift, ds_clr_reg); 3932 writel(ds_info->imval << conf->drvstr_bit, CLR_REG(ds_sel_reg));
3928 writel(sel << shift, ds_sel_reg); 3933 writel(sel << conf->drvstr_bit, ds_sel_reg);
3929 3934
3930 return 0; 3935 return 0;
3931 }
3932 3936
3933unsupport: 3937unsupport:
3934 pr_err("Pad#%d type[%d] doesn't support ds code[%d]!\n", 3938 pr_err("Pad#%d type[%d] doesn't support ds code[%d]!\n",
3935 pin, type, sel); 3939 pin, conf->type, sel);
3936 return -ENOTSUPP; 3940 return -ENOTSUPP;
3937} 3941}
3938 3942
@@ -4185,6 +4189,8 @@ static int atlas7_pinmux_suspend_noirq(struct device *dev)
4185 struct atlas7_pmx *pmx = dev_get_drvdata(dev); 4189 struct atlas7_pmx *pmx = dev_get_drvdata(dev);
4186 struct atlas7_pad_status *status; 4190 struct atlas7_pad_status *status;
4187 struct atlas7_pad_config *conf; 4191 struct atlas7_pad_config *conf;
4192 const struct atlas7_ds_info *ds_info;
4193 const struct atlas7_pull_info *pull_info;
4188 int idx; 4194 int idx;
4189 u32 bank; 4195 u32 bank;
4190 unsigned long regv; 4196 unsigned long regv;
@@ -4212,27 +4218,16 @@ save_ds_sel:
4212 goto save_pull_sel; 4218 goto save_pull_sel;
4213 4219
4214 /* Save Drive Strength selector */ 4220 /* Save Drive Strength selector */
4221 ds_info = &atlas7_ds_map[conf->type];
4215 regv = readl(pmx->regs[bank] + conf->drvstr_reg); 4222 regv = readl(pmx->regs[bank] + conf->drvstr_reg);
4216 if (PAD_T_4WE_PD == conf->type || PAD_T_4WE_PU == conf->type) 4223 status->dstr = (regv >> conf->drvstr_bit) & ds_info->mask;
4217 status->dstr = (regv >> conf->drvstr_bit) &
4218 DS_2BIT_MASK;
4219 else if (PAD_T_16ST == conf->type)
4220 status->dstr = (regv >> conf->drvstr_bit) &
4221 DS_4BIT_MASK;
4222 else if (PAD_T_M31_0204_PD == conf->type ||
4223 PAD_T_M31_0204_PU == conf->type ||
4224 PAD_T_M31_0610_PD == conf->type ||
4225 PAD_T_M31_0610_PU == conf->type)
4226 status->dstr = (regv >> conf->drvstr_bit) &
4227 DS_1BIT_MASK;
4228 4224
4229save_pull_sel: 4225save_pull_sel:
4230 /* Save Pull selector */ 4226 /* Save Pull selector */
4227 pull_info = &atlas7_pull_map[conf->type];
4231 regv = readl(pmx->regs[bank] + conf->pupd_reg); 4228 regv = readl(pmx->regs[bank] + conf->pupd_reg);
4232 status->pull = altas7_pinctrl_get_pull_sel(pmx, idx); 4229 regv = (regv >> conf->pupd_bit) & pull_info->mask;
4233 pr_debug("idx %d %p %x: %x %x %x\n", idx, 4230 status->pull = pull_info->v2s[regv].data;
4234 pmx->regs[bank], conf->mux_reg,
4235 status->func, status->pull, status->dstr);
4236 } 4231 }
4237 4232
4238 /* 4233 /*