diff options
| -rw-r--r-- | Documentation/devicetree/bindings/thermal/armada-thermal.txt | 11 | ||||
| -rw-r--r-- | drivers/thermal/armada_thermal.c | 58 |
2 files changed, 68 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt index fff93d5f92de..2a67e5135835 100644 --- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt | |||
| @@ -1,11 +1,20 @@ | |||
| 1 | * Marvell Armada 370/XP thermal management | 1 | * Marvell Armada 370/375/XP thermal management |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | 4 | ||
| 5 | - compatible: Should be set to one of the following: | 5 | - compatible: Should be set to one of the following: |
| 6 | marvell,armada370-thermal | 6 | marvell,armada370-thermal |
| 7 | marvell,armada375-thermal | ||
| 8 | marvell,armada375-z1-thermal | ||
| 7 | marvell,armadaxp-thermal | 9 | marvell,armadaxp-thermal |
| 8 | 10 | ||
| 11 | Note: As the name suggests, "marvell,armada375-z1-thermal" | ||
| 12 | applies for the SoC Z1 stepping only. On such stepping | ||
| 13 | some quirks need to be done and the register offset differs | ||
| 14 | from the one in the A0 stepping. | ||
| 15 | The operating system may auto-detect the SoC stepping and | ||
| 16 | update the compatible and register offsets at runtime. | ||
| 17 | |||
| 9 | - reg: Device's register space. | 18 | - reg: Device's register space. |
| 10 | Two entries are expected, see the examples below. | 19 | Two entries are expected, see the examples below. |
| 11 | The first one is required for the sensor register; | 20 | The first one is required for the sensor register; |
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index f84d9f077fe2..e65c5e442ed5 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c | |||
| @@ -35,6 +35,15 @@ | |||
| 35 | #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) | 35 | #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) |
| 36 | #define PMU_TDC0_START_CAL_MASK (0x1 << 25) | 36 | #define PMU_TDC0_START_CAL_MASK (0x1 << 25) |
| 37 | 37 | ||
| 38 | #define A375_Z1_CAL_RESET_LSB 0x8011e214 | ||
| 39 | #define A375_Z1_CAL_RESET_MSB 0x30a88019 | ||
| 40 | #define A375_Z1_WORKAROUND_BIT BIT(9) | ||
| 41 | |||
| 42 | #define A375_UNIT_CONTROL_SHIFT 27 | ||
| 43 | #define A375_UNIT_CONTROL_MASK 0x7 | ||
| 44 | #define A375_READOUT_INVERT BIT(15) | ||
| 45 | #define A375_HW_RESETn BIT(8) | ||
| 46 | |||
| 38 | struct armada_thermal_data; | 47 | struct armada_thermal_data; |
| 39 | 48 | ||
| 40 | /* Marvell EBU Thermal Sensor Dev Structure */ | 49 | /* Marvell EBU Thermal Sensor Dev Structure */ |
| @@ -110,6 +119,36 @@ static void armada370_init_sensor(struct platform_device *pdev, | |||
| 110 | mdelay(10); | 119 | mdelay(10); |
| 111 | } | 120 | } |
| 112 | 121 | ||
| 122 | static void armada375_init_sensor(struct platform_device *pdev, | ||
| 123 | struct armada_thermal_priv *priv) | ||
| 124 | { | ||
| 125 | unsigned long reg; | ||
| 126 | bool quirk_needed = | ||
| 127 | !!of_device_is_compatible(pdev->dev.of_node, | ||
| 128 | "marvell,armada375-z1-thermal"); | ||
| 129 | |||
| 130 | if (quirk_needed) { | ||
| 131 | /* Ensure these registers have the default (reset) values */ | ||
| 132 | writel(A375_Z1_CAL_RESET_LSB, priv->control); | ||
| 133 | writel(A375_Z1_CAL_RESET_MSB, priv->control + 0x4); | ||
| 134 | } | ||
| 135 | |||
| 136 | reg = readl(priv->control + 4); | ||
| 137 | reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); | ||
| 138 | reg &= ~A375_READOUT_INVERT; | ||
| 139 | reg &= ~A375_HW_RESETn; | ||
| 140 | |||
| 141 | if (quirk_needed) | ||
| 142 | reg |= A375_Z1_WORKAROUND_BIT; | ||
| 143 | |||
| 144 | writel(reg, priv->control + 4); | ||
| 145 | mdelay(20); | ||
| 146 | |||
| 147 | reg |= A375_HW_RESETn; | ||
| 148 | writel(reg, priv->control + 4); | ||
| 149 | mdelay(50); | ||
| 150 | } | ||
| 151 | |||
| 113 | static bool armada_is_valid(struct armada_thermal_priv *priv) | 152 | static bool armada_is_valid(struct armada_thermal_priv *priv) |
| 114 | { | 153 | { |
| 115 | unsigned long reg = readl_relaxed(priv->sensor); | 154 | unsigned long reg = readl_relaxed(priv->sensor); |
| @@ -170,6 +209,17 @@ static const struct armada_thermal_data armada370_data = { | |||
| 170 | .coef_div = 13825, | 209 | .coef_div = 13825, |
| 171 | }; | 210 | }; |
| 172 | 211 | ||
| 212 | static const struct armada_thermal_data armada375_data = { | ||
| 213 | .is_valid = armada_is_valid, | ||
| 214 | .init_sensor = armada375_init_sensor, | ||
| 215 | .is_valid_shift = 10, | ||
| 216 | .temp_shift = 0, | ||
| 217 | .temp_mask = 0x1ff, | ||
| 218 | .coef_b = 3171900000UL, | ||
| 219 | .coef_m = 10000000UL, | ||
| 220 | .coef_div = 13616, | ||
| 221 | }; | ||
| 222 | |||
| 173 | static const struct of_device_id armada_thermal_id_table[] = { | 223 | static const struct of_device_id armada_thermal_id_table[] = { |
| 174 | { | 224 | { |
| 175 | .compatible = "marvell,armadaxp-thermal", | 225 | .compatible = "marvell,armadaxp-thermal", |
| @@ -180,6 +230,14 @@ static const struct of_device_id armada_thermal_id_table[] = { | |||
| 180 | .data = &armada370_data, | 230 | .data = &armada370_data, |
| 181 | }, | 231 | }, |
| 182 | { | 232 | { |
| 233 | .compatible = "marvell,armada375-thermal", | ||
| 234 | .data = &armada375_data, | ||
| 235 | }, | ||
| 236 | { | ||
| 237 | .compatible = "marvell,armada375-z1-thermal", | ||
| 238 | .data = &armada375_data, | ||
| 239 | }, | ||
| 240 | { | ||
| 183 | /* sentinel */ | 241 | /* sentinel */ |
| 184 | }, | 242 | }, |
| 185 | }; | 243 | }; |
