From 9e7dff89053577fa016a974ccad6fac372ba15a5 Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Mon, 8 Apr 2013 16:56:46 +0800 Subject: ENGR00257947 mtd: use memcpy to replace the memcpy_fromio During the read of NOR, the kernel actually calls the inline_map_copy_from() to read the data out. And inline_map_copy_from() will use the memcpy_fromio() to do the real job. The memcpy_fromio macro maps _memcpy_fromio() in the current code. But the _memcpy_fromio() will use readb() to do the copy work one byte by one byte. This makes the read performance of NOR very slow(about 2~3MB/s). A similiar discussion could be found in: http://lists.infradead.org/pipermail/linux-arm-kernel/2009-November/003860.html This patch replace the memcpy_fromio with memcpy which is optimized by the kernel. The following is the result from mtd_speedtest with M29W256GL7AN6E: ================================================= mtd_speedtest: MTD device: 2 mtd_speedtest: not NAND flash, assume page size is 512 bytes. mtd_speedtest: MTD device size 4194304, eraseblock size 131072, page size 512, count of eraseblocks 32, pages per eraseblock 256, OOB size 0 mtd_speedtest: testing eraseblock write speed mtd_speedtest: eraseblock write speed is 845 KiB/s mtd_speedtest: testing eraseblock read speed mtd_speedtest: eraseblock read speed is 19504 KiB/s mtd_speedtest: testing page write speed mtd_speedtest: page write speed is 845 KiB/s mtd_speedtest: testing page read speed mtd_speedtest: page read speed is 19140 KiB/s mtd_speedtest: testing 2 page write speed mtd_speedtest: 2 page write speed is 846 KiB/s mtd_speedtest: testing 2 page read speed mtd_speedtest: 2 page read speed is 19320 KiB/s mtd_speedtest: Testing erase speed mtd_speedtest: erase speed is 233 KiB/s mtd_speedtest: Testing 2x multi-block erase speed mtd_speedtest: 2x multi-block erase speed is 225 KiB/s mtd_speedtest: Testing 4x multi-block erase speed mtd_speedtest: 4x multi-block erase speed is 224 KiB/s mtd_speedtest: Testing 8x multi-block erase speed mtd_speedtest: 8x multi-block erase speed is 225 KiB/s mtd_speedtest: Testing 16x multi-block erase speed mtd_speedtest: 16x multi-block erase speed is 225 KiB/s mtd_speedtest: Testing 32x multi-block erase speed mtd_speedtest: 32x multi-block erase speed is 225 KiB/s mtd_speedtest: Testing 64x multi-block erase speed mtd_speedtest: 64x multi-block erase speed is 224 KiB/s mtd_speedtest: finished ================================================= Signed-off-by: Huang Shijie --- include/linux/mtd/map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index a9e6ba46865e..418fd87002fd 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -432,7 +432,7 @@ static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned if (map->cached) memcpy(to, (char *)map->cached + from, len); else - memcpy_fromio(to, map->virt + from, len); + memcpy(to, map->virt + from, len); } static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) -- cgit v1.2.3 From 5e0d6ea2c2d36f3cd2f90a8ae37c5a3f0152dac1 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Mon, 8 Apr 2013 19:38:34 +0800 Subject: ENGR00257755-1 Revert "ASoC: wm8962: Don't automatically enable and disable" This reverts commit e2bd4d2117e1c78cfd487fb10848f3361b358057. With this patch, WM8962 couldn't work normally after SabreSD power-on. So revert it and find a better solution. Acked-by: Wang Shengjiu Signed-off-by: Nicolin Chen --- sound/soc/codecs/wm8962.c | 65 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 3ec5cc7e06c4..4d0c69ab4a5f 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2337,6 +2337,61 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5, 4, 1, 0, inmix_tlv), }; +static int sysclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); + unsigned long timeout; + int src; + int fll; + + src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK; + + switch (src) { + case 0: /* MCLK */ + fll = 0; + break; + case 0x200: /* FLL */ + fll = 1; + break; + default: + dev_err(codec->dev, "Unknown SYSCLK source %x\n", src); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (fll) { + try_wait_for_completion(&wm8962->fll_lock); + + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, + WM8962_FLL_ENA, WM8962_FLL_ENA); + + timeout = msecs_to_jiffies(5); + timeout = wait_for_completion_timeout(&wm8962->fll_lock, + timeout); + + if (wm8962->irq && timeout == 0) + dev_err(codec->dev, + "Timed out starting FLL\n"); + } + break; + + case SND_SOC_DAPM_POST_PMD: + if (fll) + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, + WM8962_FLL_ENA, 0); + break; + + default: + BUG(); + return -EINVAL; + } + + return 0; +} + static int cp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2622,7 +2677,8 @@ SND_SOC_DAPM_INPUT("DMICDAT"), SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), -SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), @@ -3362,7 +3418,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, struct _fll_div fll_div = {0}; unsigned long timeout; int ret; - int fll1 = 0; + int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; /* Any change? */ if (source == wm8962->fll_src && Fref == wm8962->fll_fref && @@ -3385,9 +3441,6 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, if (ret != 0) return ret; - /* Parameters good, disable so we can reprogram */ - snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0); - switch (fll_id) { case WM8962_FLL_MCLK: case WM8962_FLL_BCLK: @@ -3428,7 +3481,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | - WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA); + WM8962_FLL_ENA, fll1); fll1 |= WM8962_FLL_ENA; -- cgit v1.2.3 From 1db813426d5f556d2a0cec0980e5ac4c06d7ad92 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Mon, 8 Apr 2013 19:58:26 +0800 Subject: ENGR00257755-2 Revert "ENGR00256310 ASoC: imx-wm8962: Fix playback abnormally" This reverts commit 80dd80156772ff155aaf5420e41346674a9521f0. With this patch, WM8962 couldn't work normally after SabreSD power-on. So revert it and find a better solution. Acked-by: Wang Shengjiu Signed-off-by: Nicolin Chen --- sound/soc/imx/imx-wm8962.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/imx/imx-wm8962.c b/sound/soc/imx/imx-wm8962.c index c99144f2b325..8cf4bdd577de 100644 --- a/sound/soc/imx/imx-wm8962.c +++ b/sound/soc/imx/imx-wm8962.c @@ -214,14 +214,6 @@ static int imx_hifi_hw_free(struct snd_pcm_substream *substream) pr_err("Failed to set MUTE: %d\n", ret); return ret; } - - /* Disable FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, - WM8962_FLL_MCLK, 0, 0); - if (ret < 0) { - pr_err("Failed to set FLL: %d\n", ret); - return ret; - } } return 0; } -- cgit v1.2.3 From 0166fa6a636162218815ecf0921908400bb40da5 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 9 Apr 2013 09:12:31 +0800 Subject: ENGR00257755-3 Revert "ENGR00256933 ASoC: WM8962: Add delay after FLL-enable" This reverts commit 739325483d12276b80b34d7916e6cdb6d8774900. We already reverted FLL-enable code in set_fll(), so we don't need delay any more. Acked-by: Wang Shengjiu Signed-off-by: Nicolin Chen --- sound/soc/codecs/wm8962.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 4d0c69ab4a5f..9acae3004c72 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3483,8 +3483,6 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | WM8962_FLL_ENA, fll1); - fll1 |= WM8962_FLL_ENA; - dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); ret = 0; -- cgit v1.2.3 From 25b43b8b4163a48612d2d1d5684eedc33bc96b7e Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Mon, 8 Apr 2013 21:12:07 +0800 Subject: ENGR00257755-4 ASoC: WM8962: Disable FLL when chip's not being used There might be a case that SYSCLK_SRC is not FLL, but FLL's still open. If so, next time we use FLL as SYSCLK_SRC, it won't work normally. This patch disabled FLL if FLL's enabled no matter what SYSCLK_SRC is. Acked-by: Wang Shengjiu Signed-off-by: Nicolin Chen --- sound/soc/codecs/wm8962.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 9acae3004c72..b370349c0a8f 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2379,9 +2379,9 @@ static int sysclk_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: - if (fll) - snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, - WM8962_FLL_ENA, 0); + /* After Power-down, close FLL if FLL-enabled */ + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, + WM8962_FLL_ENA, 0); break; default: -- cgit v1.2.3