From nobody Tue Feb 10 20:08:36 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1520609949818433.34579217485907; Fri, 9 Mar 2018 07:39:09 -0800 (PST) Received: from localhost ([::1]:46016 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1euK6u-0007gN-W4 for importer@patchew.org; Fri, 09 Mar 2018 10:39:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50380) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1euK4y-0006Ox-4c for qemu-devel@nongnu.org; Fri, 09 Mar 2018 10:37:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1euK4w-0008ES-SD for qemu-devel@nongnu.org; Fri, 09 Mar 2018 10:37:08 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:45824) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1euK4w-0008Dv-IS for qemu-devel@nongnu.org; Fri, 09 Mar 2018 10:37:06 -0500 Received: by mail-wr0-x242.google.com with SMTP id h2so2129334wre.12 for ; Fri, 09 Mar 2018 07:37:06 -0800 (PST) Received: from x1.local (ABayonne-654-1-76-150.w86-222.abo.wanadoo.fr. [86.222.219.150]) by smtp.gmail.com with ESMTPSA id m191sm1584175wma.21.2018.03.09.07.37.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Mar 2018 07:37:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iyD+wImSrkOjxKVzq/FzC08WwIXANIQ9P3YkNYYStd8=; b=SBu2T5XfTVPWcPmif9OCY8Xz9wewFwI93XA1HVLuNARqHmyrlEbN42zaIzTTSzBPof VjHyZNFjqKa+dXpzK/XfBS6mLRABdQoXdZ8JG23V3JwAx4KwJTOaV39Su+FUhO3yLfE+ A8JlGF1edMyjsogvgHCpILgKudilS++TUC/Dtg3sk3rSsNIQdufkP9XrTUfFSV/Tcw6b HpPzNFE9k/1s+Y67SBEuhILiarIGiTWy47EmUj0k8+VJkjzVEjOKVrt2aDAFQF+/McCK bO6fB6Er/OzgWjhL0u/W4DA93tIVlNtxvsiESiVzGro7o/eHxlsjUjCqgBEKdpF/z0DT hCUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=iyD+wImSrkOjxKVzq/FzC08WwIXANIQ9P3YkNYYStd8=; b=dVrbbBDXEZwo10ZEEl4bWyMEpXyVPkpY8lSRjep/OZ3TqWm6o6MxxNwaWZR6AzhZxr 2MIeRiLWpUAKJBoFi/nY2/Caq/0U/S/fR/7SrLBpGQ8SE9ILJJhtnedPLl2zxKe71NWX /yfod/PNn66HEpJfwHp5c6Z0s6U8R9iwzWq+YKuWGcLxhgX9yigRmEpUcCkhCACIlAG5 JhRcf4L28jyuZnO16HMl/kyxDEUn1drKhGY1TKVvN7MN34Ep+qPJDKiH3nmR5568SN30 en8e0t77uIrsuDXx1M6KaTWevvjGc6GiGfypqM+JnlqiNKGGKmLKwOUWeJRZhBxo1YLh 0vWA== X-Gm-Message-State: APf1xPCn+DJHDsJZm3XIDjlweKx5DG6oO+9k1jsEBv5htWUst3Yyi1nc U9JdMw1tSWxaMdmkWJ44iiY= X-Google-Smtp-Source: AG47ELvhkrn+swamjxLlqTxKvT/JDDcU0hk8pqr/n4XuZlZNnm4CDkKKokzDOWAgOWVlQJx7FI1F6Q== X-Received: by 10.223.200.2 with SMTP id d2mr25648801wrh.81.1520609825315; Fri, 09 Mar 2018 07:37:05 -0800 (PST) From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: Alistair Francis , Peter Maydell , "Edgar E . Iglesias" Date: Fri, 9 Mar 2018 16:36:51 +0100 Message-Id: <20180309153654.13518-6-f4bug@amsat.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180309153654.13518-1-f4bug@amsat.org> References: <20180309153654.13518-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::242 Subject: [Qemu-devel] [PATCH 5/8] sdcard: Implement the UHS-I SWITCH_FUNCTION entries (Spec v3) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 [based on a patch from Alistair Francis from qemu/xilinx tag xilinx-v2015.2] Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- hw/sd/sd.c | 148 +++++++++++++++++++++++++++++++++++++++++++++----= ---- hw/sd/trace-events | 1 + 2 files changed, 127 insertions(+), 22 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 235e0518d6..b907d62aef 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -124,6 +124,7 @@ struct SDState { bool enable; uint8_t dat_lines; bool cmd_line; + bool uhs_enabled; }; =20 static const char *sd_state_name(enum SDCardStates state) @@ -563,6 +564,7 @@ static void sd_reset(DeviceState *dev) sd->expecting_acmd =3D false; sd->dat_lines =3D 0xf; sd->cmd_line =3D true; + sd->uhs_enabled =3D false; sd->multi_blk_cnt =3D 0; } =20 @@ -761,30 +763,132 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr) return ret; } =20 +/* Function Group */ +enum { + SD_FG_MIN =3D 1, + SD_FG_ACCESS_MODE =3D 1, + SD_FG_COMMAND_SYSTEM =3D 2, + SD_FG_DRIVER_STRENGTH =3D 3, + SD_FG_CURRENT_LIMIT =3D 4, + SD_FG_RSVD_5 =3D 5, + SD_FG_RSVD_6 =3D 6, + SD_FG_COUNT +}; + +/* Function name */ +#define SD_FN_COUNT 16 + +static const char *sd_fn_grp_name[SD_FG_COUNT] =3D { + [SD_FG_ACCESS_MODE] =3D "ACCESS_MODE", + [SD_FG_COMMAND_SYSTEM] =3D "COMMAND_SYSTEM", + [SD_FG_DRIVER_STRENGTH] =3D "DRIVER_STRENGTH", + [SD_FG_CURRENT_LIMIT] =3D "CURRENT_LIMIT", + [SD_FG_RSVD_5] =3D "RSVD5", + [SD_FG_RSVD_6] =3D "RSVD6", +}; + +typedef struct sd_fn_support { + const char *name; + bool uhs_only; + bool unimp; +} sd_fn_support; + +static const sd_fn_support *sd_fn_support_defs[SD_FG_COUNT] =3D { + [SD_FG_ACCESS_MODE] =3D (sd_fn_support [SD_FN_COUNT]) { + [0] =3D { .name =3D "default/SDR12" }, + [1] =3D { .name =3D "high-speed/SDR25" }, + [2] =3D { .name =3D "SDR50", .uhs_only =3D true }, + [3] =3D { .name =3D "SDR104", .uhs_only =3D true }, + [4] =3D { .name =3D "DDR50", .uhs_only =3D true }, + }, + [SD_FG_COMMAND_SYSTEM] =3D (sd_fn_support [SD_FN_COUNT]) { + [0] =3D { .name =3D "default" }, + [1] =3D { .name =3D "For eC" }, + [3] =3D { .name =3D "OTP", .unimp =3D true }, + [4] =3D { .name =3D "ASSD", .unimp =3D true }, + }, + [SD_FG_DRIVER_STRENGTH] =3D (sd_fn_support [SD_FN_COUNT]) { + [0] =3D { .name =3D "default/Type B" }, + [1] =3D { .name =3D "Type A", .uhs_only =3D true }, + [2] =3D { .name =3D "Type C", .uhs_only =3D true }, + [3] =3D { .name =3D "Type D", .uhs_only =3D true }, + }, + [SD_FG_CURRENT_LIMIT] =3D (sd_fn_support [SD_FN_COUNT]) { + [0] =3D { .name =3D "default/200mA" }, + [1] =3D { .name =3D "400mA", .uhs_only =3D true }, + [2] =3D { .name =3D "600mA", .uhs_only =3D true }, + [3] =3D { .name =3D "800mA", .uhs_only =3D true }, + }, + [SD_FG_RSVD_5] =3D (sd_fn_support [SD_FN_COUNT]) { + [0] =3D { .name =3D "default" }, + }, + [SD_FG_RSVD_6] =3D (sd_fn_support [SD_FN_COUNT]) { + [0] =3D { .name =3D "default" }, + }, +}; + +#define SD_FN_NO_INFLUENCE (1 << 15) + static void sd_function_switch(SDState *sd, uint32_t arg) { - int i, mode, new_func; - mode =3D !!(arg & 0x80000000); - - sd->data[0] =3D 0x00; /* Maximum current consumption */ - sd->data[1] =3D 0x01; - sd->data[2] =3D 0x80; /* Supported group 6 functions */ - sd->data[3] =3D 0x01; - sd->data[4] =3D 0x80; /* Supported group 5 functions */ - sd->data[5] =3D 0x01; - sd->data[6] =3D 0x80; /* Supported group 4 functions */ - sd->data[7] =3D 0x01; - sd->data[8] =3D 0x80; /* Supported group 3 functions */ - sd->data[9] =3D 0x01; - sd->data[10] =3D 0x80; /* Supported group 2 functions */ - sd->data[11] =3D 0x43; - sd->data[12] =3D 0x80; /* Supported group 1 functions */ - sd->data[13] =3D 0x03; - for (i =3D 0; i < 6; i ++) { - new_func =3D (arg >> (i * 4)) & 0x0f; - if (mode && new_func !=3D 0x0f) - sd->function_group[i] =3D new_func; - sd->data[14 + (i >> 1)] =3D new_func << ((i * 4) & 4); + int fn_grp, new_func, i; + uint8_t *data_p; + bool mode =3D extract32(arg, 31, 1); /* 0: check only, 1: do switch */ + + stw_be_p(sd->data + 0, 0x0001); /* Maximum current consumption */ + + data_p =3D &sd->data[2]; + for (fn_grp =3D SD_FG_COUNT - 1; fn_grp >=3D SD_FG_MIN; fn_grp--) { + uint16_t supported_fns =3D SD_FN_NO_INFLUENCE; + for (i =3D 0; i < SD_FN_COUNT; ++i) { + const sd_fn_support *def =3D &sd_fn_support_defs[fn_grp][i]; + + if (def->name && !def->unimp && + !(def->uhs_only && !sd->uhs_enabled)) { + supported_fns |=3D 1 << i; + } + } + stw_be_p(data_p, supported_fns); + data_p +=3D 2; + } + + assert(data_p =3D=3D &sd->data[14]); + for (fn_grp =3D SD_FG_COUNT - 1; fn_grp >=3D SD_FG_MIN; fn_grp--) { + new_func =3D (arg >> ((fn_grp - 1) * 4)) & 0x0f; + if (new_func =3D=3D 0xf) { + new_func =3D sd->function_group[fn_grp - 1]; + } else { + const sd_fn_support *def =3D &sd_fn_support_defs[fn_grp][new_f= unc]; + if (mode) { + if (!def->name) { + qemu_log_mask(LOG_GUEST_ERROR, + "Function %d not a valid for " + "function group %d\n", + new_func, fn_grp); + new_func =3D 0xf; + } else if (def->unimp) { + qemu_log_mask(LOG_UNIMP, + "Function %s (fn grp %d) not implemented= \n", + def->name, fn_grp); + new_func =3D 0xf; + } else if (def->uhs_only && !sd->uhs_enabled) { + qemu_log_mask(LOG_GUEST_ERROR, + "Function %s (fn grp %d) only " + "valid in UHS mode\n", + def->name, fn_grp); + new_func =3D 0xf; + } else { + sd->function_group[fn_grp - 1] =3D new_func; + } + } + trace_sdcard_function_select(def->name, sd_fn_grp_name[fn_grp], + mode); + } + if (!(fn_grp & 0x1)) { /* evens go in high nibble */ + *data_p =3D new_func << 4; + } else { /* odds go in low nibble */ + *(data_p++) |=3D new_func; + } } memset(&sd->data[17], 0, 47); stw_be_p(sd->data + 65, sd_crc16(sd->data, 64)); diff --git a/hw/sd/trace-events b/hw/sd/trace-events index 2059ace61f..c106541a47 100644 --- a/hw/sd/trace-events +++ b/hw/sd/trace-events @@ -42,6 +42,7 @@ sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%= " PRIx64 " size 0x%x" sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, ui= nt8_t value) "%s %20s/ CMD%02d value 0x%02x" sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int= length) "%s %20s/ CMD%02d len %d" sdcard_set_voltage(uint16_t millivolts) "%u mV" +sdcard_function_select(const char *fn_name, const char *grp_name, bool do_= switch) "Function %s (group: %s, sw: %u)" =20 # hw/sd/milkymist-memcard.c milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x = value 0x%08x" --=20 2.16.2