|
30 | 30 |
|
31 | 31 | #include <dt-bindings/arm/qcom,ids.h>
|
32 | 32 |
|
| 33 | +enum ipq806x_versions { |
| 34 | + IPQ8062_VERSION = 0, |
| 35 | + IPQ8064_VERSION, |
| 36 | + IPQ8065_VERSION, |
| 37 | +}; |
| 38 | + |
33 | 39 | #define IPQ6000_VERSION BIT(2)
|
34 | 40 |
|
35 | 41 | struct qcom_cpufreq_drv;
|
@@ -226,6 +232,61 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev,
|
226 | 232 | return ret;
|
227 | 233 | }
|
228 | 234 |
|
| 235 | +static int qcom_cpufreq_ipq8064_name_version(struct device *cpu_dev, |
| 236 | + struct nvmem_cell *speedbin_nvmem, |
| 237 | + char **pvs_name, |
| 238 | + struct qcom_cpufreq_drv *drv) |
| 239 | +{ |
| 240 | + int speed = 0, pvs = 0; |
| 241 | + int msm_id, ret = 0; |
| 242 | + u8 *speedbin; |
| 243 | + size_t len; |
| 244 | + |
| 245 | + speedbin = nvmem_cell_read(speedbin_nvmem, &len); |
| 246 | + if (IS_ERR(speedbin)) |
| 247 | + return PTR_ERR(speedbin); |
| 248 | + |
| 249 | + if (len != 4) { |
| 250 | + dev_err(cpu_dev, "Unable to read nvmem data. Defaulting to 0!\n"); |
| 251 | + ret = -ENODEV; |
| 252 | + goto exit; |
| 253 | + } |
| 254 | + |
| 255 | + get_krait_bin_format_a(cpu_dev, &speed, &pvs, speedbin); |
| 256 | + |
| 257 | + ret = qcom_smem_get_soc_id(&msm_id); |
| 258 | + if (ret) |
| 259 | + goto exit; |
| 260 | + |
| 261 | + switch (msm_id) { |
| 262 | + case QCOM_ID_IPQ8062: |
| 263 | + drv->versions = BIT(IPQ8062_VERSION); |
| 264 | + break; |
| 265 | + case QCOM_ID_IPQ8064: |
| 266 | + case QCOM_ID_IPQ8066: |
| 267 | + case QCOM_ID_IPQ8068: |
| 268 | + drv->versions = BIT(IPQ8064_VERSION); |
| 269 | + break; |
| 270 | + case QCOM_ID_IPQ8065: |
| 271 | + case QCOM_ID_IPQ8069: |
| 272 | + drv->versions = BIT(IPQ8065_VERSION); |
| 273 | + break; |
| 274 | + default: |
| 275 | + dev_err(cpu_dev, |
| 276 | + "SoC ID %u is not part of IPQ8064 family, limiting to 1.0GHz!\n", |
| 277 | + msm_id); |
| 278 | + drv->versions = BIT(IPQ8062_VERSION); |
| 279 | + break; |
| 280 | + } |
| 281 | + |
| 282 | + /* IPQ8064 speed is never fused. Only pvs values are fused. */ |
| 283 | + snprintf(*pvs_name, sizeof("speed0-pvsXX"), "speed0-pvs%d", pvs); |
| 284 | + |
| 285 | +exit: |
| 286 | + kfree(speedbin); |
| 287 | + return ret; |
| 288 | +} |
| 289 | + |
229 | 290 | static int qcom_cpufreq_ipq6018_name_version(struct device *cpu_dev,
|
230 | 291 | struct nvmem_cell *speedbin_nvmem,
|
231 | 292 | char **pvs_name,
|
@@ -302,6 +363,10 @@ static const struct qcom_cpufreq_match_data match_data_ipq6018 = {
|
302 | 363 | .get_version = qcom_cpufreq_ipq6018_name_version,
|
303 | 364 | };
|
304 | 365 |
|
| 366 | +static const struct qcom_cpufreq_match_data match_data_ipq8064 = { |
| 367 | + .get_version = qcom_cpufreq_ipq8064_name_version, |
| 368 | +}; |
| 369 | + |
305 | 370 | static int qcom_cpufreq_probe(struct platform_device *pdev)
|
306 | 371 | {
|
307 | 372 | struct qcom_cpufreq_drv *drv;
|
@@ -430,7 +495,7 @@ static const struct of_device_id qcom_cpufreq_match_list[] __initconst = {
|
430 | 495 | { .compatible = "qcom,msm8996", .data = &match_data_kryo },
|
431 | 496 | { .compatible = "qcom,qcs404", .data = &match_data_qcs404 },
|
432 | 497 | { .compatible = "qcom,ipq6018", .data = &match_data_ipq6018 },
|
433 |
| - { .compatible = "qcom,ipq8064", .data = &match_data_krait }, |
| 498 | + { .compatible = "qcom,ipq8064", .data = &match_data_ipq8064 }, |
434 | 499 | { .compatible = "qcom,apq8064", .data = &match_data_krait },
|
435 | 500 | { .compatible = "qcom,msm8974", .data = &match_data_krait },
|
436 | 501 | { .compatible = "qcom,msm8960", .data = &match_data_krait },
|
|
0 commit comments