main/linux-postmarketos-exynos4: upgrade to 5.14.5 (MR 2532)
Also add patches that should fix backlight control, add reboot modes, and work around a nasty eMMC corruption issue. [ci:skip-build]: already built successfully in CI
This commit is contained in:
parent
c21799cd2a
commit
642628a116
5 changed files with 597 additions and 5 deletions
|
@ -0,0 +1,182 @@
|
|||
From 26b78def11ca95209c1b3ee5519c594438d88f21 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Joonas=20Kylm=C3=A4l=C3=A4?= <joonas.kylmala@iki.fi>
|
||||
Date: Tue, 3 Sep 2019 10:45:08 -0400
|
||||
Subject: [PATCH] drivers: drm: Add backlight control support for s6e8aa0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Joonas Kylmälä <joonas.kylmala@iki.fi>
|
||||
---
|
||||
drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c | 83 ++++++++++++++-----
|
||||
1 file changed, 61 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c
|
||||
index 527371120266..a20369fa6b60 100644
|
||||
--- a/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c
|
||||
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c
|
||||
@@ -3,6 +3,8 @@
|
||||
* MIPI-DSI based s6e8aa0 AMOLED LCD 5.3 inch panel driver.
|
||||
*
|
||||
* Copyright (c) 2013 Samsung Electronics Co., Ltd
|
||||
+ * Copyright (C) 2019 Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
|
||||
+ * Derived from drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
|
||||
*
|
||||
* Inki Dae, <inki.dae@samsung.com>
|
||||
* Donghwa Lee, <dh09.lee@samsung.com>
|
||||
@@ -12,6 +14,7 @@
|
||||
* Andrzej Hajda <a.hajda@samsung.com>
|
||||
*/
|
||||
|
||||
+#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
@@ -25,6 +28,7 @@
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
+#include <drm/drm_print.h>
|
||||
|
||||
#define LDI_MTP_LENGTH 24
|
||||
#define GAMMA_LEVEL_NUM 25
|
||||
@@ -84,6 +88,8 @@
|
||||
#define AID_2 (0x6)
|
||||
#define AID_3 (0x7)
|
||||
|
||||
+#define MAX_BRIGHTNESS (GAMMA_LEVEL_NUM - 1)
|
||||
+
|
||||
typedef u8 s6e8aa0_gamma_table[GAMMA_TABLE_LEN];
|
||||
|
||||
struct s6e8aa0_variant {
|
||||
@@ -94,6 +100,7 @@ struct s6e8aa0_variant {
|
||||
struct s6e8aa0 {
|
||||
struct device *dev;
|
||||
struct drm_panel panel;
|
||||
+ struct backlight_device *bl_dev;
|
||||
|
||||
struct regulator_bulk_data supplies[2];
|
||||
struct gpio_desc *reset_gpio;
|
||||
@@ -109,7 +116,6 @@ struct s6e8aa0 {
|
||||
u8 version;
|
||||
u8 id;
|
||||
const struct s6e8aa0_variant *variant;
|
||||
- int brightness;
|
||||
|
||||
/* This field is tested by functions directly accessing DSI bus before
|
||||
* transfer, transfer is skipped if it is set. In case of transfer
|
||||
@@ -320,9 +326,10 @@ static void s6e8aa0_etc_elvss_control(struct s6e8aa0 *ctx)
|
||||
|
||||
static void s6e8aa0_elvss_nvm_set_v142(struct s6e8aa0 *ctx)
|
||||
{
|
||||
+ struct backlight_device *bd = ctx->bl_dev;
|
||||
u8 br;
|
||||
|
||||
- switch (ctx->brightness) {
|
||||
+ switch (bd->props.brightness) {
|
||||
case 0 ... 6: /* 30cd ~ 100cd */
|
||||
br = 0xdf;
|
||||
break;
|
||||
@@ -761,24 +768,6 @@ static const struct s6e8aa0_variant s6e8aa0_variants[] = {
|
||||
}
|
||||
};
|
||||
|
||||
-static void s6e8aa0_brightness_set(struct s6e8aa0 *ctx)
|
||||
-{
|
||||
- const u8 *gamma;
|
||||
-
|
||||
- if (ctx->error)
|
||||
- return;
|
||||
-
|
||||
- gamma = ctx->variant->gamma_tables[ctx->brightness];
|
||||
-
|
||||
- if (ctx->version >= 142)
|
||||
- s6e8aa0_elvss_nvm_set(ctx);
|
||||
-
|
||||
- s6e8aa0_dcs_write(ctx, gamma, GAMMA_TABLE_LEN);
|
||||
-
|
||||
- /* update gamma table. */
|
||||
- s6e8aa0_dcs_write_seq_static(ctx, 0xf7, 0x03);
|
||||
-}
|
||||
-
|
||||
static void s6e8aa0_panel_init(struct s6e8aa0 *ctx)
|
||||
{
|
||||
s6e8aa0_apply_level_1_key(ctx);
|
||||
@@ -790,7 +779,7 @@ static void s6e8aa0_panel_init(struct s6e8aa0 *ctx)
|
||||
|
||||
s6e8aa0_panel_cond_set(ctx);
|
||||
s6e8aa0_display_condition_set(ctx);
|
||||
- s6e8aa0_brightness_set(ctx);
|
||||
+ backlight_enable(ctx->bl_dev);
|
||||
s6e8aa0_etc_source_control(ctx);
|
||||
s6e8aa0_etc_pentile_control(ctx);
|
||||
s6e8aa0_elvss_nvm_set(ctx);
|
||||
@@ -973,6 +962,54 @@ static int s6e8aa0_parse_dt(struct s6e8aa0 *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int s6e8aa0_set_brightness(struct backlight_device *bd)
|
||||
+{
|
||||
+ struct s6e8aa0 *ctx = bl_get_data(bd);
|
||||
+ int brightness = bd->props.brightness;
|
||||
+ const u8 *gamma;
|
||||
+
|
||||
+ if (ctx->error)
|
||||
+ return ctx->error;
|
||||
+
|
||||
+ gamma = ctx->variant->gamma_tables[brightness];
|
||||
+
|
||||
+ if (ctx->version >= 142)
|
||||
+ s6e8aa0_elvss_nvm_set(ctx);
|
||||
+
|
||||
+ s6e8aa0_dcs_write(ctx, gamma, GAMMA_TABLE_LEN);
|
||||
+
|
||||
+ /* update gamma table. */
|
||||
+ s6e8aa0_dcs_write_seq_static(ctx, 0xf7, 0x03);
|
||||
+
|
||||
+ return s6e8aa0_clear_error(ctx);
|
||||
+}
|
||||
+
|
||||
+static const struct backlight_ops s6e8aa0_backlight_ops = {
|
||||
+ .update_status = s6e8aa0_set_brightness,
|
||||
+};
|
||||
+
|
||||
+static int s6e8aa0_backlight_register(struct s6e8aa0 *ctx)
|
||||
+{
|
||||
+ struct backlight_properties props = {
|
||||
+ .type = BACKLIGHT_RAW,
|
||||
+ .brightness = MAX_BRIGHTNESS,
|
||||
+ .max_brightness = MAX_BRIGHTNESS
|
||||
+ };
|
||||
+ struct device *dev = ctx->dev;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ ctx->bl_dev = devm_backlight_device_register(dev, "panel", dev, ctx,
|
||||
+ &s6e8aa0_backlight_ops,
|
||||
+ &props);
|
||||
+ if (IS_ERR(ctx->bl_dev)) {
|
||||
+ ret = PTR_ERR(ctx->bl_dev);
|
||||
+ DRM_DEV_ERROR(dev, "error registering backlight device (%d)\n",
|
||||
+ ret);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int s6e8aa0_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
@@ -1014,7 +1051,9 @@ static int s6e8aa0_probe(struct mipi_dsi_device *dsi)
|
||||
return PTR_ERR(ctx->reset_gpio);
|
||||
}
|
||||
|
||||
- ctx->brightness = GAMMA_LEVEL_NUM - 1;
|
||||
+ ret = s6e8aa0_backlight_register(ctx);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
--
|
||||
2.31.1
|
||||
|
|
@ -3,8 +3,8 @@
|
|||
# Kernel config based on: arch/arm/configs/exynos_defconfig
|
||||
|
||||
pkgname=linux-postmarketos-exynos4
|
||||
pkgver=5.14
|
||||
pkgrel=1
|
||||
pkgver=5.14.5
|
||||
pkgrel=0
|
||||
pkgdesc="Mainline kernel fork for Samsung Exynos4 devices"
|
||||
arch="armv7"
|
||||
_carch="arm"
|
||||
|
@ -28,8 +28,11 @@ source="
|
|||
https://cdn.kernel.org/pub/linux/kernel/v${_kernver%%.*}.x/linux-$_kernver.tar.xz
|
||||
$_config
|
||||
0001-ARM-decompressor-Flush-tlb-before-swiching-domain-0-.patch
|
||||
0001-drivers-drm-Add-backlight-control-support-for-s6e8aa.patch
|
||||
0001-power-supply-max17042_battery-use-VF-SOC-register-fo.patch
|
||||
0001-power_supply-max77693-change-the-supply-type-to-POWE.patch
|
||||
add-reboot-modes-to-midas.patch
|
||||
workaround-metadata-corruption-bug.patch
|
||||
initramfs.list
|
||||
init
|
||||
"
|
||||
|
@ -69,11 +72,14 @@ package() {
|
|||
}
|
||||
|
||||
sha512sums="
|
||||
8e4f3ec3d36f774280f75dc7b004a43e09417af58f12e9c9f8348976659d4cfda7ad905f306f43fed66a27922e5c45db22e46bbfa7a0b9f365012380de3b6f64 linux-5.14.tar.xz
|
||||
15fbc2cdc569b35e46a9c30ee49a6642f32284a606bb4e94177d0fd25036c799a345de4c9da5fadaef3c402c36748225f63f1a157fccff05c684d7dee667ff7e config-postmarketos-exynos4.armv7
|
||||
8213a77210a1dc58adf60bc6afe7d6a5e2931fd838f30683bb6503286b3d291ee01ae1f60adc426a36a03d857c18a5fb4d156041aed4e1542d3456e9e459bd1f linux-5.14.5.tar.xz
|
||||
445f6a42d598ab8388f1176aa0825d632007886eea9084ee7f79405b29742936b6ecd8b07b3fa6505e691d36b09ccb12e7381bb6b1dbca3fe7c55416b32d2f2a config-postmarketos-exynos4.armv7
|
||||
4bb111db4396a1981ad0883737c6594ca93701699846298b940d2ea202c666be0158a0f9ddc5b95b9147fa4cfe62639512ae78e9315f8d975b379ccc4e15da36 0001-ARM-decompressor-Flush-tlb-before-swiching-domain-0-.patch
|
||||
4d949df3906b4c7e13ae38345f8a25ec438e18b429d96d42486bb95d0cdc65d1fb68a8cd366e4040ff398633015bbd4db72e2327ad936c3a0069361392923fe1 0001-drivers-drm-Add-backlight-control-support-for-s6e8aa.patch
|
||||
166fe4dff1cdc451a9a32a5240adb93b534b8c576c5ac8d995401ebbf676385a6d8b5a6a21f556df588dee41cc4e5b8ede9eff3dd4c7835c0ca374882784d42e 0001-power-supply-max17042_battery-use-VF-SOC-register-fo.patch
|
||||
e581eb55eb4cdfdac2cbe713a5044077a9b2f15881f0bed03cc89ecb1e38d19a1c9cfbaf53ee184c4a64b10bfe071e289f4fb2230e2420e4f0042f1f301a325c 0001-power_supply-max77693-change-the-supply-type-to-POWE.patch
|
||||
4b1e0db3cb1ea369eb6b28356deaf660e3c6e73a043069dbfbe17b5b5237e854f4e400b484b4ca77a2810ecc0edaec80205c28c6793fcdc031d366b25c1b59f6 add-reboot-modes-to-midas.patch
|
||||
237f0931adfdafa57f3f194281fd28ed47b3e42636feeb7ffe4d860f2468070d399bf2d8fba075d8eec3047252573009671b45cfafc9b9de273391090f39f3e4 workaround-metadata-corruption-bug.patch
|
||||
aaff0332b90e1f9f62de1128cace934717336e54ab09de46477369fa808302482d97334e43a85ee8597c1bcab64d3484750103559fea2ce8cd51776156bf7591 initramfs.list
|
||||
09f1f214a24300696809727a7b04378887c06ca6f40803ca51a12bf2176a360b2eb8632139d6a0722094e05cb2038bdb04018a1e3d33fc2697674552ade03bee init
|
||||
"
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
From 4b0c208b9506faafbcb06629b35b4cd8cf2636ff Mon Sep 17 00:00:00 2001
|
||||
From: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
|
||||
Date: Wed, 4 Nov 2020 00:06:26 +0100
|
||||
Subject: [WIP] ARM: dts: exynos: Add reboot modes to midas
|
||||
|
||||
The values have been taken from the sec-reboot.c driver in
|
||||
the 3.0.101 smdk4412 kernel used in LineageOS which is based
|
||||
on Samsung source code releases for various devices.
|
||||
|
||||
Only the strict minimum modes have been added: the S-Boot 4.0
|
||||
bootloader is nonfree, so exporting less well known modes could
|
||||
potentially have unwanted consequences.
|
||||
|
||||
TODO:
|
||||
- After reboot to download, heimdall doesn't work while it works
|
||||
with the SMDK4412 kernel.
|
||||
- Fix reboot without arguments (Test: Try "Reboot system now"
|
||||
in a recovery after rebooting to the recovery)
|
||||
|
||||
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
|
||||
---
|
||||
arch/arm/boot/dts/exynos4412-midas.dtsi | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi
|
||||
index 0645006..fb949f9 100644
|
||||
--- a/arch/arm/boot/dts/exynos4412-midas.dtsi
|
||||
+++ b/arch/arm/boot/dts/exynos4412-midas.dtsi
|
||||
@@ -983,6 +983,29 @@
|
||||
&pmu_system_controller {
|
||||
assigned-clocks = <&pmu_system_controller 0>;
|
||||
assigned-clock-parents = <&clock CLK_XUSBXTI>;
|
||||
+
|
||||
+ /* S-Boot 4.0 */
|
||||
+ #define S5P_INFORM2 0xF008
|
||||
+ #define S5P_INFORM3 0x080C
|
||||
+ #define BOOT_MODE_PREFIX 0x12345670
|
||||
+ #define BOOT_NORMAL (BOOT_MODE_PREFIX | 0)
|
||||
+ #define BOOT_DOWNLOAD (BOOT_MODE_PREFIX | 1)
|
||||
+ #define BOOT_RECOVERY (BOOT_MODE_PREFIX | 4)
|
||||
+
|
||||
+ no-lpm-mode {
|
||||
+ compatible = "syscon-reboot";
|
||||
+ offset = <S5P_INFORM2>;
|
||||
+ value = <0x12345678>;
|
||||
+ };
|
||||
+
|
||||
+ reboot-mode {
|
||||
+ compatible = "syscon-reboot-mode";
|
||||
+ offset = <S5P_INFORM3>;
|
||||
+ mode-normal = <BOOT_NORMAL>;
|
||||
+ mode-recovery = <BOOT_RECOVERY>;
|
||||
+ mode-bootloader = <BOOT_DOWNLOAD>;
|
||||
+ mode-download = <BOOT_DOWNLOAD>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&pinctrl_0 {
|
||||
--
|
||||
cgit v1.1
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm 5.14.0 Kernel Configuration
|
||||
# Linux/arm 5.14.5 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="armv7-alpine-linux-musleabihf-gcc (Alpine 10.3.1_git20210625) 10.3.1 20210625"
|
||||
CONFIG_CC_IS_GCC=y
|
||||
|
@ -4409,6 +4409,7 @@ CONFIG_ASHMEM=y
|
|||
# CONFIG_LTE_GDM724X is not set
|
||||
# CONFIG_GS_FPGABOOT is not set
|
||||
# CONFIG_UNISYSSPAR is not set
|
||||
# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set
|
||||
# CONFIG_FB_TFT is not set
|
||||
# CONFIG_KS7010 is not set
|
||||
# CONFIG_PI433 is not set
|
||||
|
|
|
@ -0,0 +1,342 @@
|
|||
From 310f85dddffcb1070bf291ca8a97ce17e849828f Mon Sep 17 00:00:00 2001
|
||||
From: belgin <belginstirbu@hotmail.com>
|
||||
Date: Tue, 29 Jun 2021 20:31:12 +0300
|
||||
Subject: mmc: core: Workaround VTU00M 0xf1 FTL metadata corruption bug
|
||||
|
||||
Some versions of the 0xf1 revision of the firmware of the
|
||||
VTU00M eMMC from Samsung have a bug that triggers an FTL
|
||||
metadata corruption.
|
||||
|
||||
These eMMC are used at least in the Samsung Galaxy SIII
|
||||
(GT-I9300) and Galaxy Note II (GT-N7100).
|
||||
|
||||
The corrupted FTL metadata can make the eMMC CPU crash.
|
||||
|
||||
In practice as the eMMC has several hardware partitions, in
|
||||
some cases the bootloader hadware partition (which is used
|
||||
to store the phone bootloader in the Galaxy SIII and Note II)
|
||||
still works, while the main hardware partition (that contains
|
||||
the phone operating system) doesn't.
|
||||
|
||||
In other cases the eMMC crashes during the very begining of
|
||||
its boot procedure. In that case the phones botloaders can't
|
||||
be loaded anymore, which results in a black screen and no
|
||||
visible signs that the phone has been powered on.
|
||||
|
||||
This patch has been ported from the Samsung patch made to
|
||||
address this issue.
|
||||
|
||||
It uses MMC vendor specific commands to patch the eMMC
|
||||
firmware in RAM. The patch hangs the eMMC CPU right before
|
||||
the corruption is about to happen.
|
||||
|
||||
So while it's not ideal, it still better to have devices
|
||||
hanging, even repetedly, than breaking devices completely.
|
||||
|
||||
Since VTU00M eMMC firmwares are not free software nor
|
||||
redistributable, we cannot simply dump newer firmwares,
|
||||
and redistribute them. In addition the only tested way
|
||||
to do a firmware update destroys all the data on the
|
||||
eMMC (including the FTL metadata as well) in the process.
|
||||
|
||||
A proper fix would be to write a compatible free software
|
||||
eMMC firmware and to investigate the firmware update command
|
||||
that doesn't erase the FTL metadata and/or the data, however
|
||||
this could be quite time consuming.
|
||||
|
||||
References:
|
||||
- https://media.ccc.de/v/34c3-8784-emmc_hacking_or_how_i_fixed_long-dead_galaxy_s3_phones
|
||||
|
||||
TODO:
|
||||
- Adapt this patch to use the SD/eMMC hook system for eMMC cards.
|
||||
- upstream it
|
||||
|
||||
Signed-off-by: belgin <belginstirbu@hotmail.com>
|
||||
GNUtoo: Rewrite the commit message
|
||||
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
|
||||
---
|
||||
drivers/mmc/core/mmc.c | 17 ++++
|
||||
drivers/mmc/core/mmc_ops.c | 206 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/mmc/card.h | 1 +
|
||||
include/linux/mmc/core.h | 3 +
|
||||
4 files changed, 227 insertions(+)
|
||||
|
||||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
|
||||
index 7494d59..8f570fb 100644
|
||||
--- a/drivers/mmc/core/mmc.c
|
||||
+++ b/drivers/mmc/core/mmc.c
|
||||
@@ -1895,6 +1895,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
||||
if (!oldcard)
|
||||
host->card = card;
|
||||
|
||||
+ err = mmc_start_movi_operation(host->card);
|
||||
+ if (err) {
|
||||
+ pr_warn("%s: movi operation failed\n", mmc_hostname(host));
|
||||
+ goto free_card;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
|
||||
free_card:
|
||||
@@ -2274,6 +2280,17 @@ int mmc_attach_mmc(struct mmc_host *host)
|
||||
if (err)
|
||||
goto remove_card;
|
||||
|
||||
+ if (!strncmp(host->card->cid.prod_name, "VTU00M", 6) &&
|
||||
+ (host->card->cid.prv == 0xf1) &&
|
||||
+ (mmc_start_movi_smart(host->card) == 0x2))
|
||||
+ host->card->movi_ops = 0x2;
|
||||
+
|
||||
+ err = mmc_start_movi_operation(host->card);
|
||||
+ if (err) {
|
||||
+ pr_warn("%s: movi operation failed\n", mmc_hostname(host));
|
||||
+ goto remove_card;
|
||||
+ }
|
||||
+
|
||||
mmc_claim_host(host);
|
||||
return 0;
|
||||
|
||||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
|
||||
index ebad70e..0f80dd4 100644
|
||||
--- a/drivers/mmc/core/mmc_ops.c
|
||||
+++ b/drivers/mmc/core/mmc_ops.c
|
||||
@@ -829,6 +829,212 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width)
|
||||
return mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width);
|
||||
}
|
||||
|
||||
+static int mmc_send_cmd(struct mmc_host *host,
|
||||
+ u32 opcode, u32 arg, unsigned int flags, u32 *resp)
|
||||
+{
|
||||
+ int err;
|
||||
+ struct mmc_command cmd;
|
||||
+
|
||||
+ memset(&cmd, 0, sizeof(struct mmc_command));
|
||||
+
|
||||
+ cmd.opcode = opcode;
|
||||
+ cmd.arg = arg;
|
||||
+ cmd.flags = flags;
|
||||
+ *resp = 0;
|
||||
+
|
||||
+ err = mmc_wait_for_cmd(host, &cmd, 0);
|
||||
+
|
||||
+ if (!err)
|
||||
+ *resp = cmd.resp[0];
|
||||
+ else
|
||||
+ printk(KERN_ERR "[CMD%d] FAILED!!\n", cmd.opcode);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int mmc_movi_cmd(struct mmc_host *host, u32 arg)
|
||||
+{
|
||||
+ int err;
|
||||
+ u32 resp;
|
||||
+
|
||||
+ err = mmc_send_cmd(host, 62, arg,
|
||||
+ MMC_RSP_R1B | MMC_CMD_AC, &resp);
|
||||
+ mdelay(10);
|
||||
+
|
||||
+ if (!err)
|
||||
+ do {
|
||||
+ err = mmc_send_cmd(host, MMC_SEND_STATUS,
|
||||
+ host->card->rca << 16,
|
||||
+ MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC,
|
||||
+ &resp);
|
||||
+ if (err) {
|
||||
+ printk(KERN_ERR "CMD13(VC) failed\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ /*wait until READY_FOR_DATA*/
|
||||
+ } while (!(resp & 1<<8));
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int mmc_movi_erase_cmd(struct mmc_host *host, u32 arg1, u32 arg2)
|
||||
+{
|
||||
+ int err;
|
||||
+ u32 resp;
|
||||
+
|
||||
+ err = mmc_send_cmd(host, MMC_ERASE_GROUP_START, arg1,
|
||||
+ MMC_RSP_R1 | MMC_CMD_AC, &resp);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_send_cmd(host, MMC_ERASE_GROUP_END, arg2,
|
||||
+ MMC_RSP_R1 | MMC_CMD_AC, &resp);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_send_cmd(host, MMC_ERASE, 0,
|
||||
+ MMC_RSP_R1B | MMC_CMD_AC, &resp);
|
||||
+ if (!err)
|
||||
+ do {
|
||||
+ err = mmc_send_cmd(host, MMC_SEND_STATUS,
|
||||
+ host->card->rca << 16,
|
||||
+ MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC,
|
||||
+ &resp);
|
||||
+ if (err) {
|
||||
+ printk(KERN_ERR "CMD13(VC) failed\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ /*wait until READY_FOR_DATA*/
|
||||
+ } while (!(resp & 1<<8));
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int mmc_movi_read_req(struct mmc_card *card,
|
||||
+ void *data_buf, u32 arg, u32 blocks)
|
||||
+{
|
||||
+ struct mmc_request mrq = {0};
|
||||
+ struct mmc_command cmd = {0};
|
||||
+ struct mmc_data data = {0};
|
||||
+ struct scatterlist sg;
|
||||
+
|
||||
+ /*send request*/
|
||||
+ mrq.cmd = &cmd;
|
||||
+ mrq.data = &data;
|
||||
+
|
||||
+ if (blocks > 1)
|
||||
+ cmd.opcode = MMC_READ_MULTIPLE_BLOCK;
|
||||
+ else
|
||||
+ cmd.opcode = MMC_READ_SINGLE_BLOCK;
|
||||
+ cmd.arg = arg;
|
||||
+
|
||||
+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
|
||||
+
|
||||
+ data.blksz = 512;
|
||||
+ data.blocks = blocks;
|
||||
+ data.flags = MMC_DATA_READ;
|
||||
+ data.sg = &sg;
|
||||
+ data.sg_len = 1;
|
||||
+
|
||||
+ sg_init_one(&sg, data_buf, data.blksz * data.blocks);
|
||||
+
|
||||
+ mmc_set_data_timeout(&data, card);
|
||||
+
|
||||
+ mmc_wait_for_req(card->host, &mrq);
|
||||
+
|
||||
+ if (cmd.error)
|
||||
+ return cmd.error;
|
||||
+
|
||||
+ if (data.error)
|
||||
+ return data.error;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int mmc_start_movi_smart(struct mmc_card *card)
|
||||
+{
|
||||
+ int err;
|
||||
+ u8 data_buf[512];
|
||||
+ u32 date = 0;
|
||||
+
|
||||
+ err = mmc_movi_cmd(card->host, 0xEFAC62EC);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_movi_cmd(card->host, 0x0000CCEE);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_movi_read_req(card, (void *)data_buf, 0x1000, 1);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_movi_cmd(card->host, 0xEFAC62EC);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_movi_cmd(card->host, 0x00DECCEE);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ date = ((data_buf[327] << 24) | (data_buf[326] << 16) |
|
||||
+ (data_buf[325] << 8) | data_buf[324]);
|
||||
+
|
||||
+ if (date != 0x20120413) {
|
||||
+ err = -1;
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0x2;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(mmc_start_movi_smart);
|
||||
+
|
||||
+int mmc_start_movi_operation(struct mmc_card *card)
|
||||
+{
|
||||
+ int err = 0;
|
||||
+
|
||||
+ if (card->movi_ops != 0x2)
|
||||
+ return 0;
|
||||
+
|
||||
+ err = mmc_movi_cmd(card->host, 0xEFAC62EC);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ err = mmc_movi_cmd(card->host, 0x10210000);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_movi_erase_cmd(card->host, 0x00040300, 0x4A03B510);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ err = mmc_movi_erase_cmd(card->host, 0x00040304, 0x28004790);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ err = mmc_movi_erase_cmd(card->host, 0x00040308, 0xE7FED100);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ err = mmc_movi_erase_cmd(card->host, 0x0004030C, 0x0000BD10);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ err = mmc_movi_erase_cmd(card->host, 0x00040310, 0x00059D73);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ err = mmc_movi_erase_cmd(card->host, 0x0005C7EA, 0xFD89F7E3);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mmc_movi_cmd(card->host, 0xEFAC62EC);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ err = mmc_movi_cmd(card->host, 0x00DECCEE);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(mmc_start_movi_operation);
|
||||
+
|
||||
+
|
||||
static int mmc_send_hpi_cmd(struct mmc_card *card)
|
||||
{
|
||||
unsigned int busy_timeout_ms = card->ext_csd.out_of_int_time;
|
||||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
|
||||
index 42df06c..4dc435d 100644
|
||||
--- a/include/linux/mmc/card.h
|
||||
+++ b/include/linux/mmc/card.h
|
||||
@@ -313,6 +313,7 @@ struct mmc_card {
|
||||
|
||||
unsigned int bouncesz; /* Bounce buffer size */
|
||||
struct workqueue_struct *complete_wq; /* Private workqueue */
|
||||
+ unsigned int movi_ops;
|
||||
};
|
||||
|
||||
static inline bool mmc_large_sector(struct mmc_card *card)
|
||||
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
|
||||
index 29aa507..80cbc1a 100644
|
||||
--- a/include/linux/mmc/core.h
|
||||
+++ b/include/linux/mmc/core.h
|
||||
@@ -174,4 +174,7 @@ int mmc_hw_reset(struct mmc_host *host);
|
||||
int mmc_sw_reset(struct mmc_host *host);
|
||||
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card);
|
||||
|
||||
+int mmc_start_movi_smart(struct mmc_card *card);
|
||||
+int mmc_start_movi_operation(struct mmc_card *card);
|
||||
+
|
||||
#endif /* LINUX_MMC_CORE_H */
|
||||
--
|
||||
cgit v1.1
|
||||
|
Loading…
Reference in a new issue