Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

soc: mediatek: mtk-mutex: Fix confusing usage of MUTEX_MOD2

The usage of MUTEX_MOD1 and MUTEX_MOD2 for calculating mod settings
over 32 has been confusing. To improve consistency and clarity, these
defines need to fit into the same MUTEX_MOD define as possible.

However, MUTEX_MOD1 cannot be directly used for all SoCs because,
for example, the mod1 register (0x34) of MT2712 is not adjacent to
its mod0 register (0x2c). To address this, a `mutex_mod1_reg` field
is introduced in the mutex driver data structure. This allows all
SoCs to use a unified MUTEX_MOD to determine their register offsets.

With this change, the separate usage of MUTEX_MOD1 and MUTEX_MOD2 is
eliminated, simplifying the logic for obtaining offsets and mod IDs.

Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20250624103928.408194-1-jason-jh.lin@mediatek.com
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

authored by

Jason-JH Lin and committed by
AngeloGioacchino Del Regno
331db44e 19272b37

+56 -53
+56 -53
drivers/soc/mediatek/mtk-mutex.c
··· 17 17 18 18 #define MT2701_MUTEX0_MOD0 0x2c 19 19 #define MT2701_MUTEX0_SOF0 0x30 20 + #define MT2701_MUTEX0_MOD1 0x34 21 + 20 22 #define MT8183_MUTEX0_MOD0 0x30 23 + #define MT8183_MUTEX0_MOD1 0x34 21 24 #define MT8183_MUTEX0_SOF0 0x2c 22 25 23 26 #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) 24 27 #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) 25 28 #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) 26 - #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) 27 - #define DISP_REG_MUTEX_MOD1(mutex_mod_reg, n) ((mutex_mod_reg) + 0x20 * (n) + 0x4) 29 + /* 30 + * Some SoCs may have multiple MUTEX_MOD registers as more than 32 mods 31 + * are present, hence requiring multiple 32-bits registers. 32 + * 33 + * The mutex_table_mod fully represents that by defining the number of 34 + * the mod sequentially, later used as a bit number, which can be more 35 + * than 0..31. 36 + * 37 + * In order to retain compatibility with older SoCs, we perform R/W on 38 + * the single 32 bits registers, but this requires us to translate the 39 + * mutex ID bit accordingly. 40 + */ 41 + #define DISP_REG_MUTEX_MOD(mutex, id, n) ({ \ 42 + const typeof(mutex) _mutex = (mutex); \ 43 + u32 _offset = (id) < 32 ? \ 44 + _mutex->data->mutex_mod_reg : \ 45 + _mutex->data->mutex_mod1_reg; \ 46 + _offset + 0x20 * (n); \ 47 + }) 28 48 #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) 29 - #define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) 30 49 31 50 #define INT_MUTEX BIT(1) 32 51 ··· 353 334 const u8 *mutex_table_mod; 354 335 const u16 *mutex_sof; 355 336 const u16 mutex_mod_reg; 337 + const u16 mutex_mod1_reg; 356 338 const u16 mutex_sof_reg; 357 339 const bool no_clk; 358 340 }; ··· 734 714 .mutex_mod = mt2701_mutex_mod, 735 715 .mutex_sof = mt2712_mutex_sof, 736 716 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 717 + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, 737 718 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 738 719 }; 739 720 ··· 742 721 .mutex_mod = mt2712_mutex_mod, 743 722 .mutex_sof = mt2712_mutex_sof, 744 723 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 724 + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, 745 725 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 746 726 }; 747 727 ··· 750 728 .mutex_mod = mt8173_mutex_mod, 751 729 .mutex_sof = mt6795_mutex_sof, 752 730 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 731 + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, 753 732 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 754 733 }; 755 734 ··· 758 735 .mutex_mod = mt8167_mutex_mod, 759 736 .mutex_sof = mt8167_mutex_sof, 760 737 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 738 + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, 761 739 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 762 740 .no_clk = true, 763 741 }; ··· 767 743 .mutex_mod = mt8173_mutex_mod, 768 744 .mutex_sof = mt2712_mutex_sof, 769 745 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 746 + .mutex_mod1_reg = MT2701_MUTEX0_MOD1, 770 747 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 771 748 }; 772 749 ··· 775 750 .mutex_mod = mt8183_mutex_mod, 776 751 .mutex_sof = mt8183_mutex_sof, 777 752 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 753 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 778 754 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 779 755 .mutex_table_mod = mt8183_mutex_table_mod, 780 756 .no_clk = true, ··· 783 757 784 758 static const struct mtk_mutex_data mt8186_mdp_mutex_driver_data = { 785 759 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 760 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 786 761 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 787 762 .mutex_table_mod = mt8186_mdp_mutex_table_mod, 788 763 }; ··· 792 765 .mutex_mod = mt8186_mutex_mod, 793 766 .mutex_sof = mt8186_mutex_sof, 794 767 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 768 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 795 769 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 796 770 }; 797 771 ··· 800 772 .mutex_mod = mt8188_mutex_mod, 801 773 .mutex_sof = mt8188_mutex_sof, 802 774 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 775 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 803 776 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 804 777 }; 805 778 806 779 static const struct mtk_mutex_data mt8188_vpp_mutex_driver_data = { 807 780 .mutex_sof = mt8188_mutex_sof, 808 781 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 782 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 809 783 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 810 784 .mutex_table_mod = mt8188_mdp_mutex_table_mod, 811 785 }; ··· 816 786 .mutex_mod = mt8192_mutex_mod, 817 787 .mutex_sof = mt8183_mutex_sof, 818 788 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 789 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 819 790 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 820 791 }; 821 792 ··· 824 793 .mutex_mod = mt8195_mutex_mod, 825 794 .mutex_sof = mt8195_mutex_sof, 826 795 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 796 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 827 797 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 828 798 }; 829 799 830 800 static const struct mtk_mutex_data mt8195_vpp_mutex_driver_data = { 831 801 .mutex_sof = mt8195_mutex_sof, 832 802 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 803 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 833 804 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 834 805 .mutex_table_mod = mt8195_mutex_table_mod, 835 806 }; ··· 840 807 .mutex_mod = mt8365_mutex_mod, 841 808 .mutex_sof = mt8183_mutex_sof, 842 809 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 810 + .mutex_mod1_reg = MT8183_MUTEX0_MOD1, 843 811 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 844 812 .no_clk = true, 845 813 }; ··· 893 859 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 894 860 mutex[mutex->id]); 895 861 unsigned int reg; 896 - unsigned int sof_id; 862 + unsigned int sof_id, mod_id; 897 863 unsigned int offset; 898 864 899 865 WARN_ON(&mtx->mutex[mutex->id] != mutex); ··· 924 890 sof_id = MUTEX_SOF_DP_INTF1; 925 891 break; 926 892 default: 927 - if (mtx->data->mutex_mod[id] < 32) { 928 - offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 929 - mutex->id); 930 - reg = readl_relaxed(mtx->regs + offset); 931 - reg |= 1 << mtx->data->mutex_mod[id]; 932 - writel_relaxed(reg, mtx->regs + offset); 933 - } else { 934 - offset = DISP_REG_MUTEX_MOD2(mutex->id); 935 - reg = readl_relaxed(mtx->regs + offset); 936 - reg |= 1 << (mtx->data->mutex_mod[id] - 32); 937 - writel_relaxed(reg, mtx->regs + offset); 938 - } 893 + offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_mod[id], mutex->id); 894 + mod_id = mtx->data->mutex_mod[id] % 32; 895 + reg = readl_relaxed(mtx->regs + offset); 896 + reg |= BIT(mod_id); 897 + writel_relaxed(reg, mtx->regs + offset); 939 898 return; 940 899 } 941 900 ··· 944 917 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 945 918 mutex[mutex->id]); 946 919 unsigned int reg; 920 + unsigned int mod_id; 947 921 unsigned int offset; 948 922 949 923 WARN_ON(&mtx->mutex[mutex->id] != mutex); ··· 964 936 mutex->id)); 965 937 break; 966 938 default: 967 - if (mtx->data->mutex_mod[id] < 32) { 968 - offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 969 - mutex->id); 970 - reg = readl_relaxed(mtx->regs + offset); 971 - reg &= ~(1 << mtx->data->mutex_mod[id]); 972 - writel_relaxed(reg, mtx->regs + offset); 973 - } else { 974 - offset = DISP_REG_MUTEX_MOD2(mutex->id); 975 - reg = readl_relaxed(mtx->regs + offset); 976 - reg &= ~(1 << (mtx->data->mutex_mod[id] - 32)); 977 - writel_relaxed(reg, mtx->regs + offset); 978 - } 939 + offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_mod[id], mutex->id); 940 + mod_id = mtx->data->mutex_mod[id] % 32; 941 + reg = readl_relaxed(mtx->regs + offset); 942 + reg &= ~BIT(mod_id); 943 + writel_relaxed(reg, mtx->regs + offset); 979 944 break; 980 945 } 981 946 } ··· 1044 1023 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 1045 1024 mutex[mutex->id]); 1046 1025 unsigned int reg; 1047 - u32 reg_offset, id_offset = 0; 1026 + u32 offset, mod_id; 1048 1027 1049 1028 WARN_ON(&mtx->mutex[mutex->id] != mutex); 1050 1029 ··· 1054 1033 return -EINVAL; 1055 1034 } 1056 1035 1057 - /* 1058 - * Some SoCs may have multiple MUTEX_MOD registers as more than 32 mods 1059 - * are present, hence requiring multiple 32-bits registers. 1060 - * 1061 - * The mutex_table_mod fully represents that by defining the number of 1062 - * the mod sequentially, later used as a bit number, which can be more 1063 - * than 0..31. 1064 - * 1065 - * In order to retain compatibility with older SoCs, we perform R/W on 1066 - * the single 32 bits registers, but this requires us to translate the 1067 - * mutex ID bit accordingly. 1068 - */ 1069 - if (mtx->data->mutex_table_mod[idx] < 32) { 1070 - reg_offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 1071 - mutex->id); 1072 - } else { 1073 - reg_offset = DISP_REG_MUTEX_MOD1(mtx->data->mutex_mod_reg, 1074 - mutex->id); 1075 - id_offset = 32; 1076 - } 1036 + offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_table_mod[idx], mutex->id); 1037 + mod_id = mtx->data->mutex_table_mod[idx] % 32; 1077 1038 1078 - reg = readl_relaxed(mtx->regs + reg_offset); 1039 + reg = readl_relaxed(mtx->regs + offset); 1079 1040 if (clear) 1080 - reg &= ~BIT(mtx->data->mutex_table_mod[idx] - id_offset); 1041 + reg &= ~BIT(mod_id); 1081 1042 else 1082 - reg |= BIT(mtx->data->mutex_table_mod[idx] - id_offset); 1043 + reg |= BIT(mod_id); 1083 1044 1084 - writel_relaxed(reg, mtx->regs + reg_offset); 1045 + writel_relaxed(reg, mtx->regs + offset); 1085 1046 1086 1047 return 0; 1087 1048 }