From ad7d7f298cd27d6d60d73604c27265813a027ce7 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 12 Feb 2019 19:03:42 +0100 Subject: [PATCH 01/16] ARM: dts: exynos: Add support for secondary DAI to Odroid XU4 This patch extends DAPM routing and adds secondary CPU DAI entry to support the secondary audio PCM interface on Odroid XU4. Change-Id: Id20d2a064f5d29c4edf349e9a968864a48a11b46 Signed-off-by: Sylwester Nawrocki Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5422-odroidxu4.dts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts index f501f29..3f3e81f 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -36,6 +36,8 @@ compatible = "samsung,odroid-xu3-audio"; model = "Odroid-XU4"; + samsung,audio-routing = "I2S Playback", "Mixer DAI TX"; + assigned-clocks = <&clock CLK_MOUT_EPLL>, <&clock CLK_MOUT_MAU_EPLL>, <&clock CLK_MOUT_USER_MAU_EPLL>, @@ -61,7 +63,7 @@ <196608000>; cpu { - sound-dai = <&i2s0 0>; + sound-dai = <&i2s0 0>, <&i2s0 1>; }; codec { -- 2.7.4 From 974ab062962f5dbe62f8744257540a24cb9a8d74 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 4 Mar 2019 17:17:14 +0100 Subject: [PATCH 02/16] ASoC: samsung: i2s: Fix DAPM routes for capture stream This patch sets missing stream_name of capture part of the DAI driver so we can define DAPM routing properly also for the capture stream. Fixes: 64aba9bca5bd ("ASoC: samsung: i2s: Add widgets and routes for DPCM support") Change-Id: I7ac244afcd74d92cf92da1d9d7d9606285ea0360 Signed-off-by: Sylwester Nawrocki --- sound/soc/samsung/i2s.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index d3d250e..23ff857 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1134,7 +1134,7 @@ static const struct snd_soc_dapm_route samsung_i2s_dapm_routes[] = { { "Playback Mixer", NULL, "Secondary" }, { "Mixer DAI TX", NULL, "Playback Mixer" }, - { "Playback Mixer", NULL, "Mixer DAI RX" }, + { "Primary Capture", NULL, "Mixer DAI RX" }, }; static const struct snd_soc_component_driver samsung_i2s_component = { @@ -1201,6 +1201,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, dai_drv->capture.channels_max = 2; dai_drv->capture.rates = i2s_dai_data->pcm_rates; dai_drv->capture.formats = SAMSUNG_I2S_FMTS; + dai_drv->capture.stream_name = "Primary Capture"; return 0; } -- 2.7.4 From 7316ba0d62bb4f6ee663e8307ed2f352ffe24dec Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 4 Mar 2019 17:18:32 +0100 Subject: [PATCH 03/16] ARM: dts: exynos: Fix audio routing on exynos5422-odroidxu3 Add missing audio routing entry for the capture stream, this change is required to fix audio recording on Odroid XU3. Change-Id: I8db68ab3e097a0f3cfd07224016e4704e57c6635 Fixes: 885b005d232c ("ARM: dts: exynos: Add support for secondary DAI to Odroid XU3") Signed-off-by: Sylwester Nawrocki --- arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi index 15b1e9f..39a3bf9 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi @@ -29,7 +29,8 @@ "Speakers", "SPKL", "Speakers", "SPKR", "I2S Playback", "Mixer DAI TX", - "HiFi Playback", "Mixer DAI TX"; + "HiFi Playback", "Mixer DAI TX", + "Mixer DAI RX", "HiFi Capture"; assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>, <&clock CLK_MOUT_EPLL>, -- 2.7.4 From f707903a809938ef09f4bcf6368e6cc83b2fc991 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 8 Mar 2019 16:36:38 +0100 Subject: [PATCH 04/16] ASoS: samsung: odroid: Fix clock configuration for 44100 sample rate After commit fbeec965b8d1c ("ASoC: samsung: odroid: Fix 32000 sample rate handling") due to clock rounding error CODEC master clock frequency is being set to 20070401 Hz instead of 22579000 Hz. This results in too fast actual sample rate for fs=44100, e.g. 2 kHz tone has really 3555 Hz frequency (2000 Hz * 20070401/22579000 * 2). Fix this by increasing correction passed to clk_set_rate() to take into account inaccuracy of EPLL frequency properly. Change-Id: I8d08bec8e70394421c115bde1d511b730885bbe2 Signed-off-by: Sylwester Nawrocki --- sound/soc/samsung/odroid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 694512f..1dc54c4 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c @@ -91,11 +91,11 @@ static int odroid_card_be_hw_params(struct snd_pcm_substream *substream, return ret; /* - * We add 1 to the rclk_freq value in order to avoid too low clock + * We add 2 to the rclk_freq value in order to avoid too low clock * frequency values due to the EPLL output frequency not being exact * multiple of the audio sampling rate. */ - rclk_freq = params_rate(params) * rfs + 1; + rclk_freq = params_rate(params) * rfs + 2; ret = clk_set_rate(priv->sclk_i2s, rclk_freq); if (ret < 0) -- 2.7.4 From acdb73fab61be9a387771c6a86d225db5d2d6300 Mon Sep 17 00:00:00 2001 From: Jaechul Lee Date: Fri, 8 Mar 2019 08:42:55 +0900 Subject: [PATCH 05/16] ASoC: samsung: odroid: Change rfs value to 256 rfs is set 256 as a default value in I2S module. Due to clock rate setting rounding errors with rfs=512 playback is almost twice faster than original speed when the device is opened with 44.1k samplerate. pulseaudio that uses 44.1k sinks can't play the sound properly. Change-Id: I21d5553e36dcbf00802230cf1c60f5fb7df1056d Signed-off-by: Jaechul Lee --- sound/soc/samsung/odroid.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 1dc54c4..b61d866 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c @@ -74,13 +74,16 @@ static int odroid_card_be_hw_params(struct snd_pcm_substream *substream, case 44100: case 88200: pll_freq = 180633609U; - rfs = 512; + rfs = 256; break; case 32000: + pll_freq = 196608001U; + rfs = 512; + break; case 48000: case 96000: pll_freq = 196608001U; - rfs = 512; + rfs = 256; break; default: return -EINVAL; -- 2.7.4 From d0d37833d37e5f749eeffedadfa9662b6ed2d80a Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 19 Mar 2019 13:58:06 +0100 Subject: [PATCH 06/16] ARM: dts: exynos: Increase minimal ACLK400_DISP1 frequency on Exynos542x ACLK400_DISP1 bus feeds some internal buses of the display subsystem, some of which are also related to TV/Mixer hardware modules. When that bus is set to 120MHz, Exynos Mixer is not able to properly handle two XRGB display planes at FullHD-60MHz. DMA underrun happens, which in turn might result in reading data out of the configured buffer, what causes IOMMU page fault and kernel panic. This change fixes the following IOMMU fault, observed, when 2 Mixer planes were enabled: exynos-sysmmu 14650000.sysmmu: 14450000.mixer: PAGE FAULT occurred at 0x20fe9000 ------------[ cut here ]------------ kernel BUG at ../drivers/iommu/exynos-iommu.c:450! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM Modules linked in: CPU: 5 PID: 0 Comm: swapper/5 Not tainted 5.0.0-00003-g1b03088168ea #149 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) PC is at exynos_sysmmu_irq+0x1c0/0x264 LR is at lock_is_held_type+0x44/0x64 ... Reported-by: Marian Mihailescu Fixes: 5d99cc59a3c6 ("ARM: dts: exynos: Move Exynos5250 and Exynos5420 nodes under soc") Fixes: b04a62d3ade3 ("ARM: dts: exynos: Add bus nodes using VDD_INT for Exynos542x SoC") Signed-off-by: Marek Szyprowski Change-Id: I3d2f341f5e89d4631401f653d0ad9e36f26f45ad --- arch/arm/boot/dts/exynos5420.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 5451c13..d490d22 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -1300,7 +1300,7 @@ compatible = "operating-points-v2"; opp00 { - opp-hz = /bits/ 64 <120000000>; + opp-hz = /bits/ 64 <150000000>; }; opp01 { opp-hz = /bits/ 64 <200000000>; -- 2.7.4 From 1d2108db4bdec55725b3217f06ac5138ea558b87 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 2 Feb 2018 16:11:22 +0100 Subject: [PATCH 07/16] drm/exynos/mixer: fix synchronization check in interlaced mode In case of interlace mode video processor registers and mixer config register must be check to ensure internal state is in sync with shadow registers. This patch fixes page-faults in interlaced mode. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae [backport of mainline commit 2eced8e917b060587fc8ed46df41c364957a5050] Signed-off-by: Marek Szyprowski Change-Id: I8b09ed165101a7dcccd1d6e7338e0216a27f4481 --- drivers/gpu/drm/exynos/exynos_mixer.c | 10 ++++++++++ drivers/gpu/drm/exynos/regs-mixer.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index c31a3d2..94ba8cd 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -494,6 +494,7 @@ static void vp_video_buffer(struct mixer_context *ctx, spin_lock_irqsave(&ctx->reg_slock, flags); + vp_reg_write(ctx, VP_SHADOW_UPDATE, 1); /* interlace or progressive scan mode */ val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0); vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP); @@ -711,6 +712,15 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) /* interlace scan need to check shadow register */ if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { + if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags) && + vp_reg_read(ctx, VP_SHADOW_UPDATE)) + goto out; + + base = mixer_reg_read(ctx, MXR_CFG); + shadow = mixer_reg_read(ctx, MXR_CFG_S); + if (base != shadow) + goto out; + base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); if (base != shadow) diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h index c311f57..189cfa2 100644 --- a/drivers/gpu/drm/exynos/regs-mixer.h +++ b/drivers/gpu/drm/exynos/regs-mixer.h @@ -47,6 +47,7 @@ #define MXR_MO 0x0304 #define MXR_RESOLUTION 0x0310 +#define MXR_CFG_S 0x2004 #define MXR_GRAPHIC0_BASE_S 0x2024 #define MXR_GRAPHIC1_BASE_S 0x2044 -- 2.7.4 From bf75262d7163301a838c4d4f9e5c761c4aa2da46 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 19 Mar 2019 14:05:11 +0100 Subject: [PATCH 08/16] drm/exynos/mixer: fix MIXER shadow registry synchronisation code MIXER on Exynos5 SoCs uses different synchronisation method than Exynos4 to update internal state (shadow registers). Apparently the driver implements it incorrectly. The rule should be as follows: - do not request updating registers until previous request was finished, ie. MXR_CFG_LAYER_UPDATE_COUNT must be 0. - before setting registers synchronisation on VSYNC should be turned off, ie. MXR_STATUS_SYNC_ENABLE should be reset, - after finishing MXR_STATUS_SYNC_ENABLE should be set again. The patch hopefully implements it correctly. Below sample kernel log from page fault caused by the bug: [ 25.670038] exynos-sysmmu 14650000.sysmmu: 14450000.mixer: PAGE FAULT occurred at 0x2247b800 [ 25.677888] ------------[ cut here ]------------ [ 25.682164] kernel BUG at ../drivers/iommu/exynos-iommu.c:450! [ 25.687971] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM [ 25.693778] Modules linked in: [ 25.696816] CPU: 5 PID: 1553 Comm: fb-release_test Not tainted 5.0.0-rc7-01157-g5f86b1566bdd #136 [ 25.705646] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 25.711710] PC is at exynos_sysmmu_irq+0x1c0/0x264 [ 25.716470] LR is at lock_is_held_type+0x44/0x64 v2: added missing MXR_CFG_LAYER_UPDATE bit setting in mixer_enable_sync Reported-by: Marian Mihailescu Signed-off-by: Andrzej Hajda Change-Id: Idd49412e699350a7ea3a98ef7f925924e0ddf1ff --- drivers/gpu/drm/exynos/exynos_mixer.c | 110 ++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 94ba8cd..5ed9f05 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -20,6 +20,7 @@ #include "regs-vp.h" #include +#include #include #include #include @@ -349,15 +350,62 @@ static void mixer_cfg_vp_blend(struct mixer_context *ctx) mixer_reg_write(ctx, MXR_VIDEO_CFG, val); } -static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) +static bool mixer_is_synced(struct mixer_context *ctx) { - /* block update on vsync */ - mixer_reg_writemask(ctx, MXR_STATUS, enable ? - MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE); + u32 base, shadow; + if (ctx->mxr_ver == MXR_VER_16_0_33_0 || + ctx->mxr_ver == MXR_VER_128_0_0_184) + return !(mixer_reg_read(ctx, MXR_CFG) & + MXR_CFG_LAYER_UPDATE_COUNT_MASK); + + if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags) && + vp_reg_read(ctx, VP_SHADOW_UPDATE)) + return false; + + base = mixer_reg_read(ctx, MXR_CFG); + shadow = mixer_reg_read(ctx, MXR_CFG_S); + if (base != shadow) + return false; + + base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); + shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); + if (base != shadow) + return false; + + base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(1)); + shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(1)); + if (base != shadow) + return false; + + return true; +} + +static int mixer_wait_for_sync(struct mixer_context *ctx) +{ + ktime_t timeout = ktime_add_us(ktime_get(), 100000); + + while (!mixer_is_synced(ctx)) { + usleep_range(1000, 2000); + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + return 0; +} + +static void mixer_disable_sync(struct mixer_context *ctx) +{ + mixer_reg_writemask(ctx, MXR_STATUS, 0, MXR_STATUS_SYNC_ENABLE); +} + +static void mixer_enable_sync(struct mixer_context *ctx) +{ + if (ctx->mxr_ver == MXR_VER_16_0_33_0 || + ctx->mxr_ver == MXR_VER_128_0_0_184) + mixer_reg_writemask(ctx, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); + mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_SYNC_ENABLE); if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) - vp_reg_write(ctx, VP_SHADOW_UPDATE, enable ? - VP_SHADOW_UPDATE_ENABLE : 0); + vp_reg_write(ctx, VP_SHADOW_UPDATE, VP_SHADOW_UPDATE_ENABLE); } static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height) @@ -494,7 +542,6 @@ static void vp_video_buffer(struct mixer_context *ctx, spin_lock_irqsave(&ctx->reg_slock, flags); - vp_reg_write(ctx, VP_SHADOW_UPDATE, 1); /* interlace or progressive scan mode */ val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0); vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP); @@ -547,11 +594,6 @@ static void vp_video_buffer(struct mixer_context *ctx, vp_regs_dump(ctx); } -static void mixer_layer_update(struct mixer_context *ctx) -{ - mixer_reg_writemask(ctx, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); -} - static void mixer_graph_buffer(struct mixer_context *ctx, struct exynos_drm_plane *plane) { @@ -628,11 +670,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, mixer_cfg_layer(ctx, win, priority, true); mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format)); - /* layer update mandatory for mixer 16.0.33.0 */ - if (ctx->mxr_ver == MXR_VER_16_0_33_0 || - ctx->mxr_ver == MXR_VER_128_0_0_184) - mixer_layer_update(ctx); - spin_unlock_irqrestore(&ctx->reg_slock, flags); mixer_regs_dump(ctx); @@ -697,7 +734,7 @@ static void mixer_win_reset(struct mixer_context *ctx) static irqreturn_t mixer_irq_handler(int irq, void *arg) { struct mixer_context *ctx = arg; - u32 val, base, shadow; + u32 val; spin_lock(&ctx->reg_slock); @@ -711,26 +748,9 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) val &= ~MXR_INT_STATUS_VSYNC; /* interlace scan need to check shadow register */ - if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) { - if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags) && - vp_reg_read(ctx, VP_SHADOW_UPDATE)) - goto out; - - base = mixer_reg_read(ctx, MXR_CFG); - shadow = mixer_reg_read(ctx, MXR_CFG_S); - if (base != shadow) - goto out; - - base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0)); - shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0)); - if (base != shadow) - goto out; - - base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(1)); - shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(1)); - if (base != shadow) - goto out; - } + if (test_bit(MXR_BIT_INTERLACE, &ctx->flags) + && !mixer_is_synced(ctx)) + goto out; drm_crtc_handle_vblank(&ctx->crtc->base); } @@ -907,12 +927,14 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) static void mixer_atomic_begin(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *ctx = crtc->ctx; - if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) + if (!test_bit(MXR_BIT_POWERED, &ctx->flags)) return; - mixer_vsync_set_update(mixer_ctx, false); + if (mixer_wait_for_sync(ctx)) + dev_err(ctx->dev, "timeout waiting for VSYNC\n"); + mixer_disable_sync(ctx); } static void mixer_update_plane(struct exynos_drm_crtc *crtc, @@ -954,7 +976,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) return; - mixer_vsync_set_update(mixer_ctx, true); + mixer_enable_sync(mixer_ctx); exynos_crtc_handle_event(crtc); } @@ -969,7 +991,7 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) exynos_drm_pipe_clk_enable(crtc, true); - mixer_vsync_set_update(ctx, false); + mixer_disable_sync(ctx); mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); @@ -982,7 +1004,7 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) mixer_commit(ctx); - mixer_vsync_set_update(ctx, true); + mixer_enable_sync(ctx); set_bit(MXR_BIT_POWERED, &ctx->flags); } -- 2.7.4 From 4625551527e673d59d74a2e0f0483ae85dcdb207 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 1 Mar 2019 16:30:16 +0100 Subject: [PATCH 09/16] soc: samsung: asv: Wait until OPP gets released before adding new one There is currently no check whether an OPP is actually removed before attempting to add an replacement OPP. In situations when and OPP is referenced when we try to remove it and it is not already removed at the time of return from the dev_pm_opp_remove() call subsequent dev_pm_opp_add() invocation will fail. To avoid that add a polling loop with timeout as a barrier before adding new OPP. This patch should also prevent related cpufreq core issues as indicated by logs as follows. exynos_asv_update_cpu_opp cpu4 opp5, freq: 2000 missing exynos5433_asv_opp_get_voltage: arm,cortex-a57: [6] freq: 1900, voltage: 1262500 -> 1187500 cpu cpu4: _opp_add: duplicate OPPs detected. Existing: freq: 1900000000, volt: 1262500, enabled: 1. New: freq: 1900000000, volt: 1187500, enabled: 1 exynos_asv_update_cpu_opp: Failed to add OPP 1900000000 Hz/1187500 uV for cpu4 (-17) cpu cpu4: dev_pm_opp_set_rate: failed to find OPP for freq 1900000000 (-34) exynos5433_asv_opp_get_voltage: arm,cortex-a57: [9] freq: 1600, voltage: 1137500 -> 1062500 cpufreq: __target_index: Failed to change cpu frequency: -34 Change-Id: Ibf6a568cabbd5380952d97f93d27ac59f1db125b Signed-off-by: Sylwester Nawrocki --- drivers/soc/samsung/exynos-asv.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c index f416e0f..611c374 100644 --- a/drivers/soc/samsung/exynos-asv.c +++ b/drivers/soc/samsung/exynos-asv.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,7 @@ int exynos_asv_update_cpu_opp(struct device *cpu) for (i = 0; i < subsys->dvfs_nr; i++) { unsigned int new_voltage; unsigned int voltage; + int timeout = 1000; int err; opp_freq = subsys->asv_table[i][0]; @@ -66,6 +68,14 @@ int exynos_asv_update_cpu_opp(struct device *cpu) opp_freq *= MHZ; dev_pm_opp_remove(cpu, opp_freq); + while (--timeout) { + opp = dev_pm_opp_find_freq_exact(cpu, opp_freq, true); + if (IS_ERR(opp)) + break; + dev_pm_opp_put(opp); + msleep(1); + } + err = dev_pm_opp_add(cpu, opp_freq, new_voltage); if (err < 0) pr_err("%s: Failed to add OPP %u Hz/%u uV for cpu%d\n", -- 2.7.4 From d20edbc85ae24e9ec178370a4983e65ef7d83e02 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 30 Jan 2019 18:17:23 +0100 Subject: [PATCH 10/16] soc: samsung: asv: Print error code when adding an OPP fails Log error code from devm_pm_opp_add() to make any errors easier to debug. Change-Id: If418320565f1efc14d16242d8b166bea07353c54 Signed-off-by: Sylwester Nawrocki --- drivers/soc/samsung/exynos-asv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c index 611c374..71fa32f 100644 --- a/drivers/soc/samsung/exynos-asv.c +++ b/drivers/soc/samsung/exynos-asv.c @@ -78,8 +78,8 @@ int exynos_asv_update_cpu_opp(struct device *cpu) err = dev_pm_opp_add(cpu, opp_freq, new_voltage); if (err < 0) - pr_err("%s: Failed to add OPP %u Hz/%u uV for cpu%d\n", - __func__, opp_freq, new_voltage, cpu->id); + pr_err("%s: Failed to add OPP %u Hz/%u uV for cpu%d (%d)\n", + __func__, opp_freq, new_voltage, cpu->id, err); } return 0; -- 2.7.4 From 81b35ee6c4a2d5b28d9a0c2405735ab9cd216df3 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 1 Mar 2019 16:44:21 +0100 Subject: [PATCH 11/16] clk: samsung: Add CLK_IGNORE_UNUSED for Exynos5433 ABB, ASV_TB clocks Prevent disabling these clocks by the kernel until proper support is added to the ASV driver. With current code this patch is not necessarily required, because exynos_asv_init() is being called before unused clocks get disabled by clk core. However, things may break when the timings change for any reason. This patch has been tested after changing initcall type in exynos-asv.c: -late_initcall(exynos_asv_init) +late_initcall_sync(exynos_asv_init) Change-Id: I513ff391bece219318020c0bcca07e2a7938a175 Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 7e6c0c9..32ef8d6 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -1460,7 +1460,7 @@ static const struct samsung_gate_clock mif_gate_clks[] __initconst = { GATE(CLK_PCLK_GPIO_ALIVE, "pclk_gpio_alive", "div_aclk_mif_133", ENABLE_PCLK_MIF, 8, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_ABB, "pclk_abb", "div_aclk_mif_133", - ENABLE_PCLK_MIF, 7, 0, 0), + ENABLE_PCLK_MIF, 7, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_PMU_APBIF, "pclk_pmu_apbif", "div_aclk_mif_133", ENABLE_PCLK_MIF, 6, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_DDR_PHY1, "pclk_ddr_phy1", "div_aclk_mif_133", @@ -1894,7 +1894,7 @@ static const struct samsung_gate_clock peris_gate_clks[] __initconst = { /* ENABLE_SCLK_PERIS */ GATE(CLK_SCLK_ASV_TB, "sclk_asv_tb", "oscclk_efuse_common", - ENABLE_SCLK_PERIS, 10, 0, 0), + ENABLE_SCLK_PERIS, 10, CLK_IGNORE_UNUSED, 0), GATE(CLK_SCLK_TMU1, "sclk_tmu1", "oscclk_efuse_common", ENABLE_SCLK_PERIS, 4, 0, 0), GATE(CLK_SCLK_TMU0, "sclk_tmu0", "oscclk_efuse_common", -- 2.7.4 From 8e1f8520a89e44763a3683ae1965e1db1e4c4318 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 30 Jan 2019 15:57:56 +0100 Subject: [PATCH 12/16] soc: samsung: chipid: Add exynos_chipid_read_bits() function Add register read helper function needed by the ASV driver. Change-Id: I90ec78cff58ac7ff424a50309e83d37605e7cbc7 Signed-off-by: Sylwester Nawrocki --- drivers/soc/samsung/exynos-chipid.c | 6 ++++++ drivers/soc/samsung/exynos-chipid.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index 4920f0e..17d06d2 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c @@ -44,6 +44,12 @@ unsigned int exynos_chipid_read(unsigned int offset) return readl_relaxed(exynos_chipid_base + offset); } +unsigned int exynos_chipid_read_bits(unsigned int offset, unsigned int shift, + unsigned int mask) +{ + return (readl_relaxed(exynos_chipid_base + offset) >> shift) & mask; +} + static const char * __init product_id_to_soc_id(unsigned int product_id) { int i; diff --git a/drivers/soc/samsung/exynos-chipid.h b/drivers/soc/samsung/exynos-chipid.h index 826a12c..7545281 100644 --- a/drivers/soc/samsung/exynos-chipid.h +++ b/drivers/soc/samsung/exynos-chipid.h @@ -46,3 +46,5 @@ #define EXYNOS5422_KFC_DN_MASK 0x03 unsigned int exynos_chipid_read(unsigned int offset); +unsigned int exynos_chipid_read_bits(unsigned int offset, unsigned int shift, + unsigned int mask); -- 2.7.4 From 7a840072402a1356b781fce223c0240d536658ac Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 18 Feb 2019 17:37:38 +0100 Subject: [PATCH 13/16] soc: samsung: chipid: Update DT bindings documentation Document "samsung,exynos5433-chipid" compatible and add description of 'reg' property for Exynos5433. Change-Id: I9f22c76aabd46ea7aa31cfbecbb64131914e9938 Signed-off-by: Sylwester Nawrocki --- .../devicetree/bindings/arm/samsung/exynos-chipid.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt index 85c5dfd..3e30108 100644 --- a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt @@ -1,9 +1,13 @@ -SAMSUNG Exynos SoCs Chipid driver. +SAMSUNG Exynos SoC series CHIPID subsystem Required properties: -- compatible : Should at least contain "samsung,exynos4210-chipid". +- compatible : Should at least contain "samsung,exynos4210-chipid"; + For Exynos5433 SoC should also contain "samsung,exynos5433-chipid". -- reg: offset and length of the register set +- reg: Offset and length of the register set. For "samsung,exynos5433-chipid" + compatible this property should contain at least two entries, i.e. it should + describe two IO register regions, where the second one corresponds to + the ABB registers region. Example: chipid@10000000 { -- 2.7.4 From 24f72ba8b9c06d9c2964a583f2817c4219f36eda Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 30 Jan 2019 16:24:13 +0100 Subject: [PATCH 14/16] soc: samsung: chipid: Add ABB register region read helper This patch adds helper functions for accessing the ABB block registers needed by the ASV driver. Change-Id: Ida2ea622136c1abea2caffaee00b5400a8efba7d Signed-off-by: Sylwester Nawrocki --- drivers/soc/samsung/exynos-chipid.c | 24 +++++++++++++++++++++--- drivers/soc/samsung/exynos-chipid.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index 17d06d2..ce919cf 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c @@ -37,6 +37,7 @@ static const struct exynos_soc_id { { "EXYNOS5433", 0xE5433000 }, }; +static void __iomem *exynos_abb_base; static void __iomem *exynos_chipid_base; unsigned int exynos_chipid_read(unsigned int offset) @@ -50,6 +51,14 @@ unsigned int exynos_chipid_read_bits(unsigned int offset, unsigned int shift, return (readl_relaxed(exynos_chipid_base + offset) >> shift) & mask; } +unsigned int exynos_chipid_abb_read(unsigned int offset) +{ + if (WARN_ON(exynos_abb_base == NULL)) + return 0; + + return readl_relaxed(exynos_abb_base + offset); +} + static const char * __init product_id_to_soc_id(unsigned int product_id) { int i; @@ -75,13 +84,22 @@ int __init exynos_chipid_early_init(void) return -ENODEV; exynos_chipid_base = of_iomap(np, 0); - of_node_put(np); - if (!exynos_chipid_base) { - pr_err("Failed to map SoC chipid\n"); + of_node_put(np); + pr_err("Failed to map SoC CHIPID\n"); return -ENXIO; } + if (of_device_is_compatible(np, "samsung,exynos5433-chipid")) { + exynos_abb_base = of_iomap(np, 1); + if (!exynos_abb_base) { + of_node_put(np); + pr_err("Failed to map SoC CHIPID/ABB\n"); + return -ENXIO; + } + } + of_node_put(np); + product_id = exynos_chipid_read(EXYNOS_CHIPID_REG_PRO_ID); revision = product_id & EXYNOS_REV_MASK; diff --git a/drivers/soc/samsung/exynos-chipid.h b/drivers/soc/samsung/exynos-chipid.h index 7545281..92e854e 100644 --- a/drivers/soc/samsung/exynos-chipid.h +++ b/drivers/soc/samsung/exynos-chipid.h @@ -48,3 +48,4 @@ unsigned int exynos_chipid_read(unsigned int offset); unsigned int exynos_chipid_read_bits(unsigned int offset, unsigned int shift, unsigned int mask); +unsigned int exynos_chipid_abb_read(unsigned int offset); -- 2.7.4 From c3d2a4eb760a606324e5ab8c7f205d4a4e6dc097 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 1 Mar 2019 15:18:15 +0100 Subject: [PATCH 15/16] mtd: Add exynos OTP memory driver This patch adds driver for Exynos5433 OTP memory. Access to the OTP memory is required, among others, to support the Adaptive Supply Voltage feature. Partially based on code from Android SM-N910C_LL_Opensource kernel. Change-Id: If85363f1626d622f1559757eb06fd950e214e5ab Signed-off-by: Sylwester Nawrocki --- drivers/mtd/devices/Kconfig | 6 + drivers/mtd/devices/Makefile | 1 + drivers/mtd/devices/exynos_otp.c | 270 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 277 insertions(+) create mode 100644 drivers/mtd/devices/exynos_otp.c diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 64731e3..f5ee5aa 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -224,6 +224,12 @@ config MTD_ST_SPI_FSM SPI Fast Sequence Mode (FSM) Serial Flash Controller and support for a subset of connected Serial Flash devices. +config MTD_EXYNOS_OTP + tristate "Exynos SoC OTP memory driver" + depends on ARCH_EXYNOS + help + To do + if MTD_DOCG3 config BCH_CONST_M default 14 diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 94895eab..9de0e15 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_MTD_SST25L) += sst25l.o obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o obj-$(CONFIG_MTD_POWERNV_FLASH) += powernv_flash.o +obj-$(CONFIG_MTD_EXYNOS_OTP) += exynos_otp.o CFLAGS_docg3.o += -I$(src) diff --git a/drivers/mtd/devices/exynos_otp.c b/drivers/mtd/devices/exynos_otp.c new file mode 100644 index 0000000..80063f9 --- /dev/null +++ b/drivers/mtd/devices/exynos_otp.c @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Exynos5433 OTP device support + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_OTP_LOCK0 0x00 +#define REG_OTP_LOCK1 0x04 +#define REG_OTP_SECURE_READ_DATA 0x08 +#define REG_OTP_NONSECURE_READ_DATA 0x0c +#define REG_OTP_CON_CONTROL 0x10 +#define REG_OTP_CON_CONFIG 0x14 +#define REG_OTP_IF 0x18 +#define REG_OTP_INT_STATUS 0x1c +#define REG_OTP_INT_EN 0x20 +#define REG_OTP_CON_TIME_PARA_0 0x24 +#define REG_OTP_CON_TIME_PARA_1 0x28 +#define REG_OTP_CON_TIME_PARA_2 0x2c +#define REG_OTP_CON_TIME_PARA_3 0x30 +#define REG_OTP_CON_TIME_PARA_4 0x34 +#define REG_OTP_CON_TIME_PARA_5 0x38 +#define REG_OTP_CON_TIME_PARA_6 0x3c +#define REG_OTP_CON_TIME_PARA_7 0x40 +#define REG_OTP_ADD_LOCK 0x44 +#define REG_OTP_CUSTOM_LOCK0 0x48 +#define REG_OTP_CUSTOM_LOCK01 0x4c + +struct exynos_otp_priv { + struct device *dev; + struct clk_bulk_data clks[2]; + void __iomem *regs; + + struct mtd_info mtd; +}; + +static unsigned int otp_reg_read(struct exynos_otp_priv *priv, + unsigned int offset) +{ + return readl_relaxed(priv->regs + offset); +} + +static void otp_reg_write(struct exynos_otp_priv *priv, unsigned int offset, + unsigned int data) +{ + writel_relaxed(data, priv->regs + offset); +} + +static int exynos_otp_cmd_init(struct exynos_otp_priv *priv) +{ + unsigned int error_count = 0; + int result = 0; + u32 reg; + + otp_reg_write(priv, REG_OTP_CON_CONTROL, 0x01); + + while (true) { + if (otp_reg_read(priv, REG_OTP_INT_STATUS) & 0x01) + break; + + error_count++; + if (error_count > 0xffffff) { + result = -ETIMEDOUT; + break; + } + } + + reg = otp_reg_read(priv, REG_OTP_INT_STATUS); + otp_reg_write(priv, REG_OTP_INT_STATUS, (reg | 0x01)); + + return result; +} + +static int exynos_otp_cmd_standby(struct exynos_otp_priv *priv) +{ + unsigned int error_count = 0; + int result = 0; + u32 reg; + + /* Set standby command */ + reg = otp_reg_read(priv, REG_OTP_CON_CONTROL); + otp_reg_write(priv, REG_OTP_CON_CONTROL, reg | 0x08); + + while (true) { + if (otp_reg_read(priv, REG_OTP_INT_STATUS) & 0x08) + break; + + error_count++; + if (error_count > 0xffffff) { + result = -ETIMEDOUT; + break; + } + } + + reg = otp_reg_read(priv, REG_OTP_INT_STATUS); + otp_reg_write(priv, REG_OTP_INT_STATUS, reg | 0x08); + + return result; +} + +int exynos_otp_cmd_read(struct exynos_otp_priv *priv, u32 addr, u32 *val) +{ + u32 error_count = 0; + u32 reg; + + /* 1. Set address */ + /* OTP_IF: program data[31], address [14:0] */ + reg = otp_reg_read(priv, REG_OTP_IF); + reg = (reg & 0xffff0000) | (addr & 0x7fff); + otp_reg_write(priv, REG_OTP_IF, reg); + + /* 2. Set read command */ + reg = otp_reg_read(priv, REG_OTP_CON_CONTROL); + otp_reg_write(priv, REG_OTP_CON_CONTROL, reg | 0x02); + + /* 3. Check read status */ + while (true) { + reg = otp_reg_read(priv, REG_OTP_INT_STATUS); + + /* Check read done */ + if (reg & 0x02) { + dev_dbg(priv->dev, "OTP read sucessfull\n"); + break; + } + + /* Check secure fail */ + if (reg & 0x80) { + dev_err(priv->dev, "OTP error: SECURE_FAIL\n"); + return -EPERM; + } + + error_count++; + if (error_count > 0xffffff) { + dev_err(priv->dev, "OTP read timeout\n"); + return -ETIMEDOUT; + } + } + + /* 4. Checking bit [14:13] */ + reg = (otp_reg_read(priv, REG_OTP_IF) & 0x6000) >> 13; + + if (reg & 0x2) { + /* Read SECURE DATA [bit [14:13]= 1:0 or 1:1] */ + *val = otp_reg_read(priv, REG_OTP_SECURE_READ_DATA); + dev_dbg(priv->dev, "read SECURE DATA= 0x%x\n", *val); + } else if (reg & 0x1) { + /* Hardware only accessible [bit [14:13]= 0:1] */ + dev_err(priv->dev, "UNACCESSIBLE_REGION\n"); + return -EACCES; + } else if (!(reg & 0x3)) { + /* Read NON SECURE DATA [bit [14:13]= 0:0] */ + *val = otp_reg_read(priv, REG_OTP_NONSECURE_READ_DATA); + dev_dbg(priv->dev, "read NON SECURE DATA= 0x%x\n", *val); + } + + reg = otp_reg_read(priv, REG_OTP_INT_STATUS); + otp_reg_write(priv, REG_OTP_INT_STATUS, reg | 0x02); + + return 0; +} + +int exynos_mtd_read(struct mtd_info *mtd, loff_t addr, size_t len, + size_t *bytes_read, u_char *buf) +{ + struct exynos_otp_priv *priv = mtd->priv; + u32 *data = (u32 *)buf; + u32 val = 0; + unsigned int count; + int result, ret; + + ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clks), priv->clks); + if (ret < 0) + return ret; + + result = exynos_otp_cmd_init(priv); + if (result < 0) { + dev_err(priv->dev, "otp_cmd_init() failed: %d\n", result); + clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clks), priv->clks); + return result; + } + + len = (len + 3) / 4; + + for (count = 0; count < len; count++) { + result = exynos_otp_cmd_read(priv, addr + count /** 32*/, &val); + if (result < 0) { + dev_err(priv->dev, "OTP read failed: %d\n", result); + break; + } + data[count] = val; + *bytes_read += 4; + } + + ret = exynos_otp_cmd_standby(priv); + if (ret < 0) + dev_err(priv->dev, "otp_cmd_standby() failed: %d\n", ret); + + clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clks), priv->clks); + + return result; +} + +static int exynos_otp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct exynos_otp_priv *priv; + struct resource *mem_res; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->regs = devm_ioremap_resource(dev, mem_res); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + priv->clks[0].id = "pclk"; + priv->clks[1].id = "sclk"; + + priv->dev = dev; + + ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clks), priv->clks); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, priv); + + priv->mtd.owner = THIS_MODULE; + priv->mtd.priv = priv; + priv->mtd.size = 0x10000; /* FIXME: Replace with real OTP size */ + priv->mtd.writesize = 4; + priv->mtd.name = "exynos5433-otp"; + priv->mtd._read = exynos_mtd_read; + + return mtd_device_register(&priv->mtd, NULL, 0); +} + +static const struct of_device_id exynos_otp_of_match[] = { + { .compatible = "samsung,exynos5433-otp" }, + { }, +}; +MODULE_DEVICE_TABLE(of, exynos_otp_of_match); + +static struct platform_driver exynos_otp_driver = { + .probe = exynos_otp_probe, + .driver = { + .of_match_table = exynos_otp_of_match, + .name = "exynos-otp", + }, +}; +module_platform_driver(exynos_otp_driver); + +MODULE_DESCRIPTION("Exynos SoC OTP memory driver"); +MODULE_LICENSE("GPL v2"); -- 2.7.4 From 0c91bf5f19e4149e55af50e3c46e3873f23378c3 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 30 Jan 2019 16:53:06 +0100 Subject: [PATCH 16/16] arm64: dts: exynos: Update Exynos5433 CHIPID node Extend the register region to also cover the ASV table region and add reg entries for the ABB registers region. Change-Id: I64704397a0cd12cb9a019b83f45fd23890da458b Signed-off-by: Sylwester Nawrocki --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index fa8d52e..2558b1e 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -315,8 +315,9 @@ }; chipid@10000000 { - compatible = "samsung,exynos4210-chipid"; - reg = <0x10000000 0x100>; + compatible = "samsung,exynos5433-chipid", + "samsung,exynos4210-chipid"; + reg = <0x10000000 0x4100>, <0x105D0000 0x100>; }; xxti: xxti { -- 2.7.4