summaryrefslogtreecommitdiff
path: root/samsung/exynos_drm_dsim.c
diff options
context:
space:
mode:
authorLong Ling <longling@google.com>2020-05-01 18:31:09 -0700
committerLong Ling <longling@google.com>2020-10-16 18:07:14 -0700
commitedba45e0a786a4db0472b9e58f705ea660dd8bfd (patch)
tree468b5a9de81c3e9f60db02d1cfca4fedcf72abfd /samsung/exynos_drm_dsim.c
parent03489694c0dd390d8c1a30b9433b271c38e747f5 (diff)
downloaddisplay-edba45e0a786a4db0472b9e58f705ea660dd8bfd.tar.gz
drivers/drm/samsung: parse pll features from device tree
These features are used to config PLL at run time. Bug: 139663511 Change-Id: I5afdd20534a8264f319463049b9bd116ec0e6628 Signed-off-by: Long Ling <longling@google.com>
Diffstat (limited to 'samsung/exynos_drm_dsim.c')
-rw-r--r--samsung/exynos_drm_dsim.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/samsung/exynos_drm_dsim.c b/samsung/exynos_drm_dsim.c
index 8a92710..6b89079 100644
--- a/samsung/exynos_drm_dsim.c
+++ b/samsung/exynos_drm_dsim.c
@@ -280,6 +280,8 @@ static void dsim_modes_release(struct dsim_pll_params *pll_params)
kfree(pll_params->params[i]);
kfree(pll_params->params);
}
+ kfree(pll_params->features);
+
kfree(pll_params);
}
@@ -402,6 +404,99 @@ static int dsim_of_parse_modes(struct device_node *entry,
return 0;
}
+static struct dsim_pll_features *dsim_of_get_pll_features(
+ struct dsim_device *dsim, struct device_node *np)
+{
+ u64 range64[2];
+ u32 range32[2];
+ struct dsim_pll_features *pll_features;
+
+ pll_features = kzalloc(sizeof(*pll_features), GFP_KERNEL);
+ if (!pll_features)
+ return NULL;
+
+ if (of_property_read_u64(np, "pll-input", &pll_features->finput) < 0) {
+ dsim_err(dsim, "%s failed to get pll-input\n", __func__);
+ goto read_node_fail;
+ }
+
+ if (of_property_read_u64(np, "pll-optimum",
+ &pll_features->foptimum) < 0) {
+ dsim_err(dsim, "%s failed to get pll-optimum\n", __func__);
+ goto read_node_fail;
+ }
+
+ if (of_property_read_u64_array(np, "pll-out-range", range64, 2) < 0) {
+ dsim_err(dsim, "%s failed to get pll-out-range\n", __func__);
+ goto read_node_fail;
+ }
+ pll_features->fout_min = range64[0];
+ pll_features->fout_max = range64[1];
+
+ if (of_property_read_u64_array(np, "pll-vco-range", range64, 2) < 0) {
+ dsim_err(dsim, "%s failed to get pll-vco-range\n", __func__);
+ goto read_node_fail;
+ }
+ pll_features->fvco_min = range64[0];
+ pll_features->fvco_max = range64[1];
+
+ if (of_property_read_u32(np, "te-idle", &pll_features->te_idle) < 0) {
+ dsim_err(dsim, "%s failed to get te-idle\n", __func__);
+ goto read_node_fail;
+ }
+
+ if (of_property_read_u32(np, "te-var", &pll_features->te_var) < 0) {
+ dsim_err(dsim, "%s failed to get te-var\n", __func__);
+ goto read_node_fail;
+ }
+
+ if (of_property_read_u32_array(np, "p-range", range32, 2) < 0) {
+ dsim_err(dsim, "%s failed to get p-range\n", __func__);
+ goto read_node_fail;
+ }
+ pll_features->p_min = range32[0];
+ pll_features->p_max = range32[1];
+
+ if (of_property_read_u32_array(np, "m-range", range32, 2) < 0) {
+ dsim_err(dsim, "%s failed to get m-range\n", __func__);
+ goto read_node_fail;
+ }
+ pll_features->m_min = range32[0];
+ pll_features->m_max = range32[1];
+
+ if (of_property_read_u32_array(np, "s-range", range32, 2) < 0) {
+ dsim_err(dsim, "%s failed to get s-range\n", __func__);
+ goto read_node_fail;
+ }
+ pll_features->s_min = range32[0];
+ pll_features->s_max = range32[1];
+
+ if (of_property_read_u32(np, "k-bits", &pll_features->k_bits) < 0) {
+ dsim_err(dsim, "%s failed to get k-bits\n", __func__);
+ goto read_node_fail;
+ }
+
+ dsim_debug(dsim, "pll features: input %llu, optimum%llu\n",
+ pll_features->finput, pll_features->foptimum);
+ dsim_debug(dsim, "pll features: output(%llu, %llu)\n",
+ pll_features->fout_min, pll_features->fout_max);
+ dsim_debug(dsim, "pll features: vco (%llu, %llu)\n",
+ pll_features->fvco_min, pll_features->fout_max);
+ dsim_debug(dsim, "te idle %u, te var %u\n", pll_features->te_idle,
+ pll_features->te_var);
+ dsim_debug(dsim, "pll limits: p(%u, %u), m(%u, %u), s(%u, %u), k(%u)\n",
+ pll_features->p_min, pll_features->p_max,
+ pll_features->m_min, pll_features->m_max,
+ pll_features->s_min, pll_features->s_max,
+ pll_features->k_bits);
+
+ return pll_features;
+
+read_node_fail:
+ kfree(pll_features);
+ return NULL;
+}
+
static struct dsim_pll_params *dsim_of_get_clock_mode(struct dsim_device *dsim)
{
struct device *dev = dsim->dev;
@@ -459,6 +554,8 @@ static struct dsim_pll_params *dsim_of_get_clock_mode(struct dsim_device *dsim)
pll_params->num_modes++;
}
+ pll_params->features = dsim_of_get_pll_features(dsim, np);
+
of_node_put(np);
of_node_put(mode_np);
of_node_put(entry);