clk: qcom: Specify LE device endianness
Subsystems (3)
PATCH 1/1 clk: qcom: Specify LE device endianness
All these clock controllers are little endian devices, but so far we've been relying on the regmap mmio bus handling this for us without explicitly stating that fact. After commit 4a98da2164cf (regmap-mmio: Use native endianness for read/write, 2015-10-29), the regmap mmio bus will read/write with the __raw_*() IO accessors, instead of using the readl/writel() APIs that do proper byte swapping for little endian devices.
So if we're running on a big endian processor and haven't specified the endianness explicitly in the regmap config or in DT, we're going to switch from doing little endian byte swapping to big endian accesses without byte swapping, leading to some confusing results. On my apq8074 dragonboard, this causes the device to fail to boot as we access the clock controller with big endian IO accesses even though the device is little endian.
Specify the endianness explicitly so that the regmap core properly byte swaps the accesses for us.
---
FYI, the regmap patch also converts the I/O accessors to use "relaxed" accessors that don't have any barrier semantics. So we've opened up the possibility of reads and writes overlapping each other whereas before that would be handled by the barriers buried in readl/writel, etc. I haven't yet fully examined the qcom clk driver for this problem, but I'm fairly certain we'll need to add some barriers in the driver to handle this. Alternatively we could add explicit barriers.
drivers/clk/qcom/gcc-apq8084.c | 1 + drivers/clk/qcom/gcc-ipq806x.c | 1 + drivers/clk/qcom/gcc-msm8660.c | 1 + drivers/clk/qcom/gcc-msm8916.c | 1 + drivers/clk/qcom/gcc-msm8960.c | 2 ++ drivers/clk/qcom/gcc-msm8974.c | 1 + drivers/clk/qcom/lcc-ipq806x.c | 1 + drivers/clk/qcom/lcc-msm8960.c | 1 + drivers/clk/qcom/mmcc-apq8084.c | 1 + drivers/clk/qcom/mmcc-msm8960.c | 2 ++ drivers/clk/qcom/mmcc-msm8974.c | 1 + 11 files changed, 13 insertions(+)
drivers/clk/qcom/gcc-apq8084.c +1 -0
@@ -3587,6 +3587,7 @@ static const struct regmap_config gcc_apq8084_regmap_config = { .val_bits = 32, .max_register = 0x1fc0, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc gcc_apq8084_desc = {
drivers/clk/qcom/gcc-ipq806x.c +1 -0
@@ -3002,6 +3002,7 @@ static const struct regmap_config gcc_ipq806x_regmap_config = { .val_bits = 32, .max_register = 0x3e40, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc gcc_ipq806x_desc = {
drivers/clk/qcom/gcc-msm8660.c +1 -0
@@ -2702,6 +2702,7 @@ static const struct regmap_config gcc_msm8660_regmap_config = { .val_bits = 32, .max_register = 0x363c, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc gcc_msm8660_desc = {
drivers/clk/qcom/gcc-msm8916.c +1 -0
@@ -3336,6 +3336,7 @@ static const struct regmap_config gcc_msm8916_regmap_config = { .val_bits = 32, .max_register = 0x80000, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc gcc_msm8916_desc = {
drivers/clk/qcom/gcc-msm8960.c +2 -0
@@ -3468,6 +3468,7 @@ static const struct regmap_config gcc_msm8960_regmap_config = { .val_bits = 32, .max_register = 0x3660, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct regmap_config gcc_apq8064_regmap_config = {
@@ -3476,6 +3477,7 @@ static const struct regmap_config gcc_apq8064_regmap_config = { .val_bits = 32, .max_register = 0x3880, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc gcc_msm8960_desc = {
drivers/clk/qcom/gcc-msm8974.c +1 -0
@@ -2680,6 +2680,7 @@ static const struct regmap_config gcc_msm8974_regmap_config = { .val_bits = 32, .max_register = 0x1fc0, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc gcc_msm8974_desc = {
drivers/clk/qcom/lcc-ipq806x.c +1 -0
@@ -419,6 +419,7 @@ static const struct regmap_config lcc_ipq806x_regmap_config = { .val_bits = 32, .max_register = 0xfc, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc lcc_ipq806x_desc = {
drivers/clk/qcom/lcc-msm8960.c +1 -0
@@ -524,6 +524,7 @@ static const struct regmap_config lcc_msm8960_regmap_config = { .val_bits = 32, .max_register = 0xfc, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc lcc_msm8960_desc = {
drivers/clk/qcom/mmcc-apq8084.c +1 -0
@@ -3368,6 +3368,7 @@ static const struct regmap_config mmcc_apq8084_regmap_config = { .val_bits = 32, .max_register = 0x5104, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc mmcc_apq8084_desc = {
drivers/clk/qcom/mmcc-msm8960.c +2 -0
@@ -3029,6 +3029,7 @@ static const struct regmap_config mmcc_msm8960_regmap_config = { .val_bits = 32, .max_register = 0x334, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct regmap_config mmcc_apq8064_regmap_config = {
@@ -3037,6 +3038,7 @@ static const struct regmap_config mmcc_apq8064_regmap_config = { .val_bits = 32, .max_register = 0x350, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc mmcc_msm8960_desc = {
drivers/clk/qcom/mmcc-msm8974.c +1 -0
@@ -2594,6 +2594,7 @@ static const struct regmap_config mmcc_msm8974_regmap_config = { .val_bits = 32, .max_register = 0x5104, .fast_io = true, + .val_format_endian = REGMAP_ENDIAN_LITTLE, };static const struct qcom_cc_desc mmcc_msm8974_desc = {
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Quoted 16 lines · Stephen Boyd
All these clock controllers are little endian devices, but so far we've been relying on the regmap mmio bus handling this for us without explicitly stating that fact. After commit
4a98da2164cf(regmap-mmio: Use native endianness for read/write, 2015-10-29), the regmap mmio bus will read/write with the __raw_*() IO accessors, instead of using the readl/writel() APIs that do proper byte swapping for little endian devices.So if we're running on a big endian processor and haven't specified the endianness explicitly in the regmap config or in DT, we're going to switch from doing little endian byte swapping to big endian accesses without byte swapping, leading to some confusing results. On my apq8074 dragonboard, this causes the device to fail to boot as we access the clock controller with big endian IO accesses even though the device is little endian.
Quoted 7 lines
Specify the endianness explicitly so that the regmap core properly byte swaps the accesses for us.
Reported-by Kevin Hilman <[email protected]>Cc Simon Arlott <[email protected]>Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>
Verified that this patch on top of next-20151118 gets my 2 8x94 boards booting again with big-endian kernel.
Kevin
Quoted 16 lines · Stephen Boyd
All these clock controllers are little endian devices, but so far we've been relying on the regmap mmio bus handling this for us without explicitly stating that fact. After commit
4a98da2164cf(regmap-mmio: Use native endianness for read/write, 2015-10-29), the regmap mmio bus will read/write with the __raw_*() IO accessors, instead of using the readl/writel() APIs that do proper byte swapping for little endian devices.So if we're running on a big endian processor and haven't specified the endianness explicitly in the regmap config or in DT, we're going to switch from doing little endian byte swapping to big endian accesses without byte swapping, leading to some confusing results. On my apq8074 dragonboard, this causes the device to fail to boot as we access the clock controller with big endian IO accesses even though the device is little endian.
Quoted 7 lines
Specify the endianness explicitly so that the regmap core properly byte swaps the accesses for us.
Reported-by Kevin Hilman <[email protected]>Cc Simon Arlott <[email protected]>Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>
The kernelci.org bot also reported boot failures[1] for the apq8016-sbc in next-20151120 with CONFIG_CPU_BIG_ENDIAN=y enabled. I've bisected the failure down to the same offending remap-mmio patch listed above. I've confirmed this patch applied on top of next-20151120 fixes the boot issue for the apq8016-sbc as well.
Any updates or comments on this patch? I'd like to see this fix in linux-next, as it has been broken for over a week and could be masking new issues.
Cheers,
Tyler
[1] http://kernelci.org/boot/all/job/next/kernel/next-20151120/
Quoted 33 lines · Tyler Baker
Quoted 16 lines · Stephen Boyd
All these clock controllers are little endian devices, but so far we've been relying on the regmap mmio bus handling this for us without explicitly stating that fact. After commit
4a98da2164cf(regmap-mmio: Use native endianness for read/write, 2015-10-29), the regmap mmio bus will read/write with the __raw_*() IO accessors, instead of using the readl/writel() APIs that do proper byte swapping for little endian devices.So if we're running on a big endian processor and haven't specified the endianness explicitly in the regmap config or in DT, we're going to switch from doing little endian byte swapping to big endian accesses without byte swapping, leading to some confusing results. On my apq8074 dragonboard, this causes the device to fail to boot as we access the clock controller with big endian IO accesses even though the device is little endian.
Quoted 7 lines
Specify the endianness explicitly so that the regmap core properly byte swaps the accesses for us.
Reported-by Kevin Hilman <[email protected]>Cc Simon Arlott <[email protected]>Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>Tested-by Tyler Baker <[email protected]>The kernelci.org bot also reported boot failures[1] for the apq8016-sbc in next-20151120 with
CONFIG_CPU_BIG_ENDIAN=yenabled. I've bisected the failure down to the same offending remap-mmio patch listed above. I've confirmed this patch applied on top of next-20151120 fixes the boot issue for the apq8016-sbc as well.
Quoted 3 lines
Any updates or comments on this patch? I'd like to see this fix in linux-next, as it has been broken for over a week and could be masking new issues.
Yeah I've been lagging on applying patches. I need to send more patches for other regmap-mmio users too. I'll cook those up right now and send them off.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Stephen Boyd
AppliedQuoted 16 lines · Stephen Boyd
All these clock controllers are little endian devices, but so far we've been relying on the regmap mmio bus handling this for us without explicitly stating that fact. After commit
4a98da2164cf(regmap-mmio: Use native endianness for read/write, 2015-10-29), the regmap mmio bus will read/write with the __raw_*() IO accessors, instead of using the readl/writel() APIs that do proper byte swapping for little endian devices.So if we're running on a big endian processor and haven't specified the endianness explicitly in the regmap config or in DT, we're going to switch from doing little endian byte swapping to big endian accesses without byte swapping, leading to some confusing results. On my apq8074 dragonboard, this causes the device to fail to boot as we access the clock controller with big endian IO accesses even though the device is little endian.
Quoted 8 lines
Specify the endianness explicitly so that the regmap core properly byte swaps the accesses for us.
Reported-by Kevin Hilman <[email protected]>Cc Simon Arlott <[email protected]>Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>---
Applied to clk-next
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project