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

Configure Feed

Select the types of activity you want to include in your feed.

slimbus: qcom-ngd-ctrl: add support for 44.1 Khz frequency

Add support for 44.1Khz frequency by dynamically calculating the slimbus
parameters instead of statically defining them.

Co-developed-by: Prudhvi Yarlagadda <pyarlaga@codeaurora.org>
Signed-off-by: Prudhvi Yarlagadda <pyarlaga@codeaurora.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20221118065246.6835-5-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Krzysztof Kozlowski and committed by
Greg Kroah-Hartman
4594cb4b 434d2572

+59 -5
+59 -5
drivers/slimbus/qcom-ngd-ctrl.c
··· 944 944 return ret; 945 945 } 946 946 947 + static int qcom_slim_calc_coef(struct slim_stream_runtime *rt, int *exp) 948 + { 949 + struct slim_controller *ctrl = rt->dev->ctrl; 950 + int coef; 951 + 952 + if (rt->ratem * ctrl->a_framer->superfreq < rt->rate) 953 + rt->ratem++; 954 + 955 + coef = rt->ratem; 956 + *exp = 0; 957 + 958 + /* 959 + * CRM = Cx(2^E) is the formula we are using. 960 + * Here C is the coffecient and E is the exponent. 961 + * CRM is the Channel Rate Multiplier. 962 + * Coefficeint should be either 1 or 3 and exponenet 963 + * should be an integer between 0 to 9, inclusive. 964 + */ 965 + while (1) { 966 + while ((coef & 0x1) != 0x1) { 967 + coef >>= 1; 968 + *exp = *exp + 1; 969 + } 970 + 971 + if (coef <= 3) 972 + break; 973 + 974 + coef++; 975 + } 976 + 977 + /* 978 + * we rely on the coef value (1 or 3) to set a bit 979 + * in the slimbus message packet. This bit is 980 + * BIT(5) which is the segment rate coefficient. 981 + */ 982 + if (coef == 1) { 983 + if (*exp > 9) 984 + return -EIO; 985 + coef = 0; 986 + } else { 987 + if (*exp > 8) 988 + return -EIO; 989 + coef = 1; 990 + } 991 + 992 + return coef; 993 + } 994 + 947 995 static int qcom_slim_ngd_enable_stream(struct slim_stream_runtime *rt) 948 996 { 949 997 struct slim_device *sdev = rt->dev; ··· 1015 967 struct slim_port *port = &rt->ports[i]; 1016 968 1017 969 if (txn.msg->num_bytes == 0) { 1018 - int seg_interval = SLIM_SLOTS_PER_SUPERFRAME/rt->ratem; 1019 - int exp; 970 + int exp = 0, coef = 0; 1020 971 1021 972 wbuf[txn.msg->num_bytes++] = sdev->laddr; 1022 973 wbuf[txn.msg->num_bytes] = rt->bps >> 2 | 1023 974 (port->ch.aux_fmt << 6); 1024 975 1025 - /* Data channel segment interval not multiple of 3 */ 1026 - exp = seg_interval % 3; 1027 - if (exp) 976 + /* calculate coef dynamically */ 977 + coef = qcom_slim_calc_coef(rt, &exp); 978 + if (coef < 0) { 979 + dev_err(&sdev->dev, 980 + "%s: error calculating coef %d\n", __func__, 981 + coef); 982 + return -EIO; 983 + } 984 + 985 + if (coef) 1028 986 wbuf[txn.msg->num_bytes] |= BIT(5); 1029 987 1030 988 txn.msg->num_bytes++;