diff options
Diffstat (limited to 'drivers/pinctrl/sirf')
-rw-r--r-- | drivers/pinctrl/sirf/pinctrl-atlas7.c | 193 |
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 */ | ||
3513 | struct map_data { | 3514 | struct 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 | */ | ||
3518 | struct atlas7_pull_info { | 3526 | struct 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 | */ | ||
3616 | struct 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 | |||
3624 | static 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 | */ | ||
3649 | struct atlas7_ds_info { | ||
3650 | u8 type; | ||
3651 | u8 mask; | ||
3652 | u8 imval; | ||
3653 | u8 reserved; | ||
3654 | }; | ||
3655 | |||
3656 | static 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 | |||
3600 | static inline u32 atlas7_pin_to_bank(u32 pin) | 3667 | static 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 | ||
3802 | struct atlas7_ds_info { | ||
3803 | u32 ma; | ||
3804 | u32 ds_16st; | ||
3805 | u32 ds_4we; | ||
3806 | u32 ds_0204m31; | ||
3807 | u32 ds_0610m31; | ||
3808 | }; | ||
3809 | |||
3810 | const 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 | |||
3829 | static u32 convert_current_to_drive_strength(u32 type, u32 ma) | 3869 | static 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 | ||
3850 | static 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 | |||
3866 | static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev, | 3890 | static 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 | ||
3933 | unsupport: | 3937 | unsupport: |
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 | ||
4229 | save_pull_sel: | 4225 | save_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 | /* |