From nobody Tue May 14 05:45:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1671398476; cv=none; d=zohomail.com; s=zohoarc; b=YsCBMuggkJVS0YY7nrKwypuuVxoZ1XYKKngPQG8WJHvbwfhRRXm8mrgWCgy5pib8Uvdp7cjDWuyiz8Ip1bvh8R2BvRbaEW0iS2EeQy5kmCYP95gekoxyrjkCii2Ac1n/7oCE06SyL+I9BYORgAt3Cu+c+rG8QNWSH5oyVU2x8yk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671398476; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0iC1DLdK7rM2+2JgfrCCzhIOuJpyhzdQ5lAlF2+ubgA=; b=S+O+TNyu1LJ6CuyV0PXuiNuEq/L1erZXdn+FBPx8fgGrfKLh2eKBf3T8pnkPhvViLe3OnxO3+LAbpt6fOj/as2JxAA78MUIIAOxSk01sUrmil/gLWvdYUuDOiwIZZ+DGJQ76EiesvmojSMAgm0278H9ZEt4+9N+KN+8CvkrWHvQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671398476396381.5664558478968; Sun, 18 Dec 2022 13:21:16 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p714g-00018b-Sz; Sun, 18 Dec 2022 16:19:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p714C-00011S-5b; Sun, 18 Dec 2022 16:19:28 -0500 Received: from mail-lf1-x134.google.com ([2a00:1450:4864:20::134]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p7149-0001xA-DI; Sun, 18 Dec 2022 16:19:27 -0500 Received: by mail-lf1-x134.google.com with SMTP id m29so10871161lfo.11; Sun, 18 Dec 2022 13:19:24 -0800 (PST) Received: from penguin.lxd (213-67-202-254-no43.tbcn.telia.com. [213.67.202.254]) by smtp.googlemail.com with ESMTPSA id w7-20020a05651234c700b0049464d89e40sm902620lfr.72.2022.12.18.13.19.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 13:19:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0iC1DLdK7rM2+2JgfrCCzhIOuJpyhzdQ5lAlF2+ubgA=; b=ZAs8rjnmf1SvizKBaGFz+0X0uLqJp+H4QIfqQEkb9RhMRvpTwAo+zVoFiR0/kq4qrI /M3RmmQ1/1LsJxFSX0tMQ8K0beAlZ0rBaVnucdL9XrDhTFxMsL6k9sVVfXV+aPNNvKzb g0SYhObg9PAqN4Ap3NoOp63j13Y5axsQ72D35iKJ4AIV+LYjURJFj0fS95QJkhh8kO9C //cZb2Zqd92cro5NkTMd3vKfARgDe+awxNYkNUD2O5Tlwi/0E3N/2eJk/sZrh1v1kWdi zmmf+npiP8e4b+oiqJF+s0yWjCAbBRtBSbmBsoxSTqQyMAH/LHaNaXUYXvU92NrMUBTR 82HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0iC1DLdK7rM2+2JgfrCCzhIOuJpyhzdQ5lAlF2+ubgA=; b=dHLoQJkJZ375OnQbemzl8uOnuuscIAjFeemit6GH0nvADhVFq6PxbRORSoKqMj+5r2 GKb9PoUprEsy/xvTboBKLm2GJWDRCwVBn/XxLhPTEpxxsb+ggscdz7jDSgVvsxitbaXr qHV28mOceFITM9xSQXC3G89yEkpjpK7Jw8WHSvThfnDNh49c+ucu7kKmsNy4FhgyxQm0 DV7fzWF17as6CUulzhfIkb7FEYmJr2KQFaRouZVBQaBR3+51zqvmJAwJLWspl7qRu+J1 1hNM6UfnbYn/9kWpyyYGiLCFuwyDesgZOLhAa7VyoNCrVUwZRTwQHRcJnI22aYD0GCc/ Z2VA== X-Gm-Message-State: ANoB5pmcuU4Iuv6Ug8cmwULz2sEDXAWa4iMFJn0KGlih5IJ9h0Cd60TT Py0uKEH8A7/txDFZOSVP9v4zvBiJfuNiFUH8 X-Google-Smtp-Source: AA0mqf53teNEECK3POdNn5rbXhgi0YLit2A6TvcXgdNBTR/Abq+rz088cGlzr0nhhlzu88v/vQZA3A== X-Received: by 2002:a05:6512:3414:b0:4b4:b5d3:6603 with SMTP id i20-20020a056512341400b004b4b5d36603mr18070802lfr.32.1671398363230; Sun, 18 Dec 2022 13:19:23 -0800 (PST) From: Strahinja Jankovic X-Google-Original-From: Strahinja Jankovic To: Peter Maydell Cc: Beniamino Galvani , Niek Linnenbank , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Strahinja Jankovic Subject: [PATCH v2 1/7] hw/misc: Allwinner-A10 Clock Controller Module Emulation Date: Sun, 18 Dec 2022 22:19:12 +0100 Message-Id: <20221218211918.3592-2-strahinja.p.jankovic@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> References: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::134; envelope-from=strahinjapjankovic@gmail.com; helo=mail-lf1-x134.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1671398477072100003 Content-Type: text/plain; charset="utf-8" During SPL boot several Clock Controller Module (CCM) registers are read, most important are PLL and Tuning, as well as divisor registers. This patch adds these registers and initializes reset values from user's guide. Signed-off-by: Strahinja Jankovic Reviewed-by: Niek Linnenbank --- hw/arm/Kconfig | 1 + hw/arm/allwinner-a10.c | 7 + hw/misc/Kconfig | 3 + hw/misc/allwinner-a10-ccm.c | 224 ++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + include/hw/arm/allwinner-a10.h | 2 + include/hw/misc/allwinner-a10-ccm.h | 67 +++++++++ 7 files changed, 305 insertions(+) create mode 100644 hw/misc/allwinner-a10-ccm.c create mode 100644 include/hw/misc/allwinner-a10-ccm.h diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 17fcde8e1c..14f52b41af 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -319,6 +319,7 @@ config ALLWINNER_A10 select AHCI select ALLWINNER_A10_PIT select ALLWINNER_A10_PIC + select ALLWINNER_A10_CCM select ALLWINNER_EMAC select SERIAL select UNIMP diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 79082289ea..86baeeeca2 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -26,6 +26,7 @@ #include "hw/usb/hcd-ohci.h" =20 #define AW_A10_MMC0_BASE 0x01c0f000 +#define AW_A10_CCM_BASE 0x01c20000 #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 @@ -46,6 +47,8 @@ static void aw_a10_init(Object *obj) =20 object_initialize_child(obj, "timer", &s->timer, TYPE_AW_A10_PIT); =20 + object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM); + object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC); =20 object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI); @@ -103,6 +106,10 @@ static void aw_a10_realize(DeviceState *dev, Error **e= rrp) memory_region_add_subregion(get_system_memory(), 0x00000000, &s->sram_= a); create_unimplemented_device("a10-sram-ctrl", 0x01c00000, 4 * KiB); =20 + /* Clock Control Module */ + sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE); + /* FIXME use qdev NIC properties instead of nd_table[] */ if (nd_table[0].used) { qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC); diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index cbabe9f78c..ed07bf4133 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -174,4 +174,7 @@ config VIRT_CTRL config LASI bool =20 +config ALLWINNER_A10_CCM + bool + source macio/Kconfig diff --git a/hw/misc/allwinner-a10-ccm.c b/hw/misc/allwinner-a10-ccm.c new file mode 100644 index 0000000000..68146ee340 --- /dev/null +++ b/hw/misc/allwinner-a10-ccm.c @@ -0,0 +1,224 @@ +/* + * Allwinner A10 Clock Control Module emulation + * + * Copyright (C) 2022 Strahinja Jankovic + * + * This file is derived from Allwinner H3 CCU, + * by Niek Linnenbank. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "hw/sysbus.h" +#include "migration/vmstate.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "hw/misc/allwinner-a10-ccm.h" + +/* CCM register offsets */ +enum { + REG_PLL1_CFG =3D 0x0000, /* PLL1 Control */ + REG_PLL1_TUN =3D 0x0004, /* PLL1 Tuning */ + REG_PLL2_CFG =3D 0x0008, /* PLL2 Control */ + REG_PLL2_TUN =3D 0x000C, /* PLL2 Tuning */ + REG_PLL3_CFG =3D 0x0010, /* PLL3 Control */ + REG_PLL4_CFG =3D 0x0018, /* PLL4 Control */ + REG_PLL5_CFG =3D 0x0020, /* PLL5 Control */ + REG_PLL5_TUN =3D 0x0024, /* PLL5 Tuning */ + REG_PLL6_CFG =3D 0x0028, /* PLL6 Control */ + REG_PLL6_TUN =3D 0x002C, /* PLL6 Tuning */ + REG_PLL7_CFG =3D 0x0030, /* PLL7 Control */ + REG_PLL1_TUN2 =3D 0x0038, /* PLL1 Tuning2 */ + REG_PLL5_TUN2 =3D 0x003C, /* PLL5 Tuning2 */ + REG_PLL8_CFG =3D 0x0040, /* PLL8 Control */ + REG_OSC24M_CFG =3D 0x0050, /* OSC24M Control */ + REG_CPU_AHB_APB0_CFG =3D 0x0054, /* CPU, AHB and APB0 Divide Ratio= */ +}; + +#define REG_INDEX(offset) (offset / sizeof(uint32_t)) + +/* CCM register reset values */ +enum { + REG_PLL1_CFG_RST =3D 0x21005000, + REG_PLL1_TUN_RST =3D 0x0A101000, + REG_PLL2_CFG_RST =3D 0x08100010, + REG_PLL2_TUN_RST =3D 0x00000000, + REG_PLL3_CFG_RST =3D 0x0010D063, + REG_PLL4_CFG_RST =3D 0x21009911, + REG_PLL5_CFG_RST =3D 0x11049280, + REG_PLL5_TUN_RST =3D 0x14888000, + REG_PLL6_CFG_RST =3D 0x21009911, + REG_PLL6_TUN_RST =3D 0x00000000, + REG_PLL7_CFG_RST =3D 0x0010D063, + REG_PLL1_TUN2_RST =3D 0x00000000, + REG_PLL5_TUN2_RST =3D 0x00000000, + REG_PLL8_CFG_RST =3D 0x21009911, + REG_OSC24M_CFG_RST =3D 0x00138013, + REG_CPU_AHB_APB0_CFG_RST =3D 0x00010010, +}; + +static uint64_t allwinner_a10_ccm_read(void *opaque, hwaddr offset, + unsigned size) +{ + const AwA10ClockCtlState *s =3D AW_A10_CCM(opaque); + const uint32_t idx =3D REG_INDEX(offset); + + switch (offset) { + case REG_PLL1_CFG: + case REG_PLL1_TUN: + case REG_PLL2_CFG: + case REG_PLL2_TUN: + case REG_PLL3_CFG: + case REG_PLL4_CFG: + case REG_PLL5_CFG: + case REG_PLL5_TUN: + case REG_PLL6_CFG: + case REG_PLL6_TUN: + case REG_PLL7_CFG: + case REG_PLL1_TUN2: + case REG_PLL5_TUN2: + case REG_PLL8_CFG: + case REG_OSC24M_CFG: + case REG_CPU_AHB_APB0_CFG: + break; + case 0x158 ... AW_A10_CCM_IOSIZE: + qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n", + __func__, (uint32_t)offset); + return 0; + default: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n", + __func__, (uint32_t)offset); + return 0; + } + + return s->regs[idx]; +} + +static void allwinner_a10_ccm_write(void *opaque, hwaddr offset, + uint64_t val, unsigned size) +{ + AwA10ClockCtlState *s =3D AW_A10_CCM(opaque); + const uint32_t idx =3D REG_INDEX(offset); + + switch (offset) { + case REG_PLL1_CFG: + case REG_PLL1_TUN: + case REG_PLL2_CFG: + case REG_PLL2_TUN: + case REG_PLL3_CFG: + case REG_PLL4_CFG: + case REG_PLL5_CFG: + case REG_PLL5_TUN: + case REG_PLL6_CFG: + case REG_PLL6_TUN: + case REG_PLL7_CFG: + case REG_PLL1_TUN2: + case REG_PLL5_TUN2: + case REG_PLL8_CFG: + case REG_OSC24M_CFG: + case REG_CPU_AHB_APB0_CFG: + break; + case 0x158 ... AW_A10_CCM_IOSIZE: + qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n", + __func__, (uint32_t)offset); + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n", + __func__, (uint32_t)offset); + break; + } + + s->regs[idx] =3D (uint32_t) val; +} + +static const MemoryRegionOps allwinner_a10_ccm_ops =3D { + .read =3D allwinner_a10_ccm_read, + .write =3D allwinner_a10_ccm_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, + .impl.min_access_size =3D 4, +}; + +static void allwinner_a10_ccm_reset_enter(Object *obj, ResetType type) +{ + AwA10ClockCtlState *s =3D AW_A10_CCM(obj); + + /* Set default values for registers */ + s->regs[REG_INDEX(REG_PLL1_CFG)] =3D REG_PLL1_CFG_RST; + s->regs[REG_INDEX(REG_PLL1_TUN)] =3D REG_PLL1_TUN_RST; + s->regs[REG_INDEX(REG_PLL2_CFG)] =3D REG_PLL2_CFG_RST; + s->regs[REG_INDEX(REG_PLL2_TUN)] =3D REG_PLL2_TUN_RST; + s->regs[REG_INDEX(REG_PLL3_CFG)] =3D REG_PLL3_CFG_RST; + s->regs[REG_INDEX(REG_PLL4_CFG)] =3D REG_PLL4_CFG_RST; + s->regs[REG_INDEX(REG_PLL5_CFG)] =3D REG_PLL5_CFG_RST; + s->regs[REG_INDEX(REG_PLL5_TUN)] =3D REG_PLL5_TUN_RST; + s->regs[REG_INDEX(REG_PLL6_CFG)] =3D REG_PLL6_CFG_RST; + s->regs[REG_INDEX(REG_PLL6_TUN)] =3D REG_PLL6_TUN_RST; + s->regs[REG_INDEX(REG_PLL7_CFG)] =3D REG_PLL7_CFG_RST; + s->regs[REG_INDEX(REG_PLL1_TUN2)] =3D REG_PLL1_TUN2_RST; + s->regs[REG_INDEX(REG_PLL5_TUN2)] =3D REG_PLL5_TUN2_RST; + s->regs[REG_INDEX(REG_PLL8_CFG)] =3D REG_PLL8_CFG_RST; + s->regs[REG_INDEX(REG_OSC24M_CFG)] =3D REG_OSC24M_CFG_RST; + s->regs[REG_INDEX(REG_CPU_AHB_APB0_CFG)] =3D REG_CPU_AHB_APB0_CFG_RST; +} + +static void allwinner_a10_ccm_init(Object *obj) +{ + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + AwA10ClockCtlState *s =3D AW_A10_CCM(obj); + + /* Memory mapping */ + memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_ccm_ops, s, + TYPE_AW_A10_CCM, AW_A10_CCM_IOSIZE); + sysbus_init_mmio(sbd, &s->iomem); +} + +static const VMStateDescription allwinner_a10_ccm_vmstate =3D { + .name =3D "allwinner-a10-ccm", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, AwA10ClockCtlState, AW_A10_CCM_REGS_NUM= ), + VMSTATE_END_OF_LIST() + } +}; + +static void allwinner_a10_ccm_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + rc->phases.enter =3D allwinner_a10_ccm_reset_enter; + dc->vmsd =3D &allwinner_a10_ccm_vmstate; +} + +static const TypeInfo allwinner_a10_ccm_info =3D { + .name =3D TYPE_AW_A10_CCM, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_init =3D allwinner_a10_ccm_init, + .instance_size =3D sizeof(AwA10ClockCtlState), + .class_init =3D allwinner_a10_ccm_class_init, +}; + +static void allwinner_a10_ccm_register(void) +{ + type_register_static(&allwinner_a10_ccm_info); +} + +type_init(allwinner_a10_ccm_register) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index ed0598dc9e..c828dbeb26 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -38,6 +38,7 @@ subdir('macio') =20 softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c')) =20 +softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_CCM', if_true: files('allwinner= -a10-ccm.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-c= cu.c')) specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpu= cfg.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-d= ramc.c')) diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index a76dc7b84d..45d0fc2f7e 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -12,6 +12,7 @@ #include "hw/usb/hcd-ohci.h" #include "hw/usb/hcd-ehci.h" #include "hw/rtc/allwinner-rtc.h" +#include "hw/misc/allwinner-a10-ccm.h" =20 #include "target/arm/cpu.h" #include "qom/object.h" @@ -30,6 +31,7 @@ struct AwA10State { /*< public >*/ =20 ARMCPU cpu; + AwA10ClockCtlState ccm; AwA10PITState timer; AwA10PICState intc; AwEmacState emac; diff --git a/include/hw/misc/allwinner-a10-ccm.h b/include/hw/misc/allwinne= r-a10-ccm.h new file mode 100644 index 0000000000..7f22532efa --- /dev/null +++ b/include/hw/misc/allwinner-a10-ccm.h @@ -0,0 +1,67 @@ +/* + * Allwinner A10 Clock Control Module emulation + * + * Copyright (C) 2022 Strahinja Jankovic + * + * This file is derived from Allwinner H3 CCU, + * by Niek Linnenbank. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HW_MISC_ALLWINNER_A10_CCM_H +#define HW_MISC_ALLWINNER_A10_CCM_H + +#include "qom/object.h" +#include "hw/sysbus.h" + +/** + * @name Constants + * @{ + */ + +/** Size of register I/O address space used by CCM device */ +#define AW_A10_CCM_IOSIZE (0x400) + +/** Total number of known registers */ +#define AW_A10_CCM_REGS_NUM (AW_A10_CCM_IOSIZE / sizeof(uint32_t)) + +/** @} */ + +/** + * @name Object model + * @{ + */ + +#define TYPE_AW_A10_CCM "allwinner-a10-ccm" +OBJECT_DECLARE_SIMPLE_TYPE(AwA10ClockCtlState, AW_A10_CCM) + +/** @} */ + +/** + * Allwinner A10 CCM object instance state. + */ +struct AwA10ClockCtlState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + /** Maps I/O registers in physical memory */ + MemoryRegion iomem; + + /** Array of hardware registers */ + uint32_t regs[AW_A10_CCM_REGS_NUM]; +}; + +#endif /* HW_MISC_ALLWINNER_H3_CCU_H */ --=20 2.30.2 From nobody Tue May 14 05:45:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1671398499; cv=none; d=zohomail.com; s=zohoarc; b=S7FYPHeDzlldOfoHcdf5ULDZT9lCYn3utHbmHbuYEOlGKKpT0VjJpQU3N8uPNNQDlzJed1T1kXMhVsz3ptGwB+huLdz3wFEpigKbZoYGwYvZowRTmDUpzEeJKl2QYwCtLeVu++LEed9TIqZXeA+D52i9gP6yhHl+F8P6wQoN33s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671398499; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=IA9DLwdDIWXg6Vm5V2G0ugLwqd09BSX4sLQfHIli23s=; b=Q/lwFo2wyaflO1ykSSzg151r+ddZ+0QQYeT1+oeyu40QhY/NxPvfqSqsG1Jfw4aG2K7VHxpWwvMP+8JTCYjx/jAoYXd+H68XyW/aiSoow0gKKDjHNonIK3M9zJDgpTs7gB1e40+Ht4orDre1BmkZsq2KB+MbPHMr64jl2ANqBu8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671398499262763.0857345129161; Sun, 18 Dec 2022 13:21:39 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p714b-00016F-Fg; Sun, 18 Dec 2022 16:19:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p714E-00012Y-0B; Sun, 18 Dec 2022 16:19:30 -0500 Received: from mail-lj1-x235.google.com ([2a00:1450:4864:20::235]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p714A-0001xM-2h; Sun, 18 Dec 2022 16:19:29 -0500 Received: by mail-lj1-x235.google.com with SMTP id a19so7389802ljk.0; Sun, 18 Dec 2022 13:19:25 -0800 (PST) Received: from penguin.lxd (213-67-202-254-no43.tbcn.telia.com. [213.67.202.254]) by smtp.googlemail.com with ESMTPSA id w7-20020a05651234c700b0049464d89e40sm902620lfr.72.2022.12.18.13.19.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 13:19:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IA9DLwdDIWXg6Vm5V2G0ugLwqd09BSX4sLQfHIli23s=; b=Hvef4si2oX8zCE4SAuQcMLHm1aCVqCzNwidOSa7augyVgE1yRxedTaKdLYS/F9+fEI DLCiknfavCDX8/wjNfxjMFeckYIyN7L5PWTrIoIuRvOYNZQPggONsFExDtdc6vhU2I8a VdqRhtmJnUxVK2ZEWZhihQczRZ0MJv6lpttjXJSWqAmrpMhLtn+LkkwZaf22lQi6HHvs x5mO3TIOYtps6Epw4A95stFQPTFGAB/Y8hSf5oP0FrBjpfA6odu7iRZoP53sE2JrpsxJ fLb3HuS6LqbxaWrJON5lK5LPz1MFZp7BfznjBgfYXadh0zEUvx9CRPsEINNe5766k1PR wfdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IA9DLwdDIWXg6Vm5V2G0ugLwqd09BSX4sLQfHIli23s=; b=mkXeTYfSRMfpPvt/OlRCYpp9NQ5j9DCJIOkjKya9JHA1W8CrwVca3PecE/sx0IdLMa 5uXNxtbXCD/DmNfzTXowWF62RlbY+QNXqkb87cURqdewV5Pfy2GB8zsITLsqvrTjpg4J sMrD6tOqW8cG2JDfLTOmsbB4sCtD2qZfCJEZ7dh+KHr9upM62J0VZ7sV1X61AoXUeFEL rHvN21nmopCopvsdkYeGKGHnvDdYlIgyhZap5q7LTKiMfT6r8qkTHzrlL6QpoK2o91Lj Q3SvmPiUxYm+tS8+U/UuS+G2jtYnRxqZK9cHKVxGFcwSuLt79pC2u1kRgCzOV0IWOMsN DKLA== X-Gm-Message-State: AFqh2krUMBygfbVbhPstaJOY/G8pZgvHIAdbJuuzy3IAsVVlO+z7NQn8 7tL/TYZN7vufosbhbycUpIE= X-Google-Smtp-Source: AMrXdXvbLhnx1vGfOeaTVisUE/XV3bfpWr0LDAexFLSOYtJpf35whdW9fNlMgZre6q6jjSGDaMazwg== X-Received: by 2002:a2e:a725:0:b0:27f:795c:ed95 with SMTP id s37-20020a2ea725000000b0027f795ced95mr1376326lje.42.1671398363978; Sun, 18 Dec 2022 13:19:23 -0800 (PST) From: Strahinja Jankovic X-Google-Original-From: Strahinja Jankovic To: Peter Maydell Cc: Beniamino Galvani , Niek Linnenbank , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Strahinja Jankovic Subject: [PATCH v2 2/7] hw/misc: Allwinner A10 DRAM Controller Emulation Date: Sun, 18 Dec 2022 22:19:13 +0100 Message-Id: <20221218211918.3592-3-strahinja.p.jankovic@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> References: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::235; envelope-from=strahinjapjankovic@gmail.com; helo=mail-lj1-x235.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1671398501203100003 Content-Type: text/plain; charset="utf-8" During SPL boot several DRAM Controller registers are used. Most important registers are those related to DRAM initialization and calibration, where SPL initiates process and waits until certain bit is set/cleared. This patch adds these registers, initializes reset values from user's guide and updates state of registers as SPL expects it. Signed-off-by: Strahinja Jankovic Reviewed-by: Niek Linnenbank --- hw/arm/Kconfig | 1 + hw/arm/allwinner-a10.c | 7 + hw/misc/Kconfig | 3 + hw/misc/allwinner-a10-dramc.c | 179 ++++++++++++++++++++++++++ hw/misc/meson.build | 1 + include/hw/arm/allwinner-a10.h | 2 + include/hw/misc/allwinner-a10-dramc.h | 68 ++++++++++ 7 files changed, 261 insertions(+) create mode 100644 hw/misc/allwinner-a10-dramc.c create mode 100644 include/hw/misc/allwinner-a10-dramc.h diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 14f52b41af..140f142ae5 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -320,6 +320,7 @@ config ALLWINNER_A10 select ALLWINNER_A10_PIT select ALLWINNER_A10_PIC select ALLWINNER_A10_CCM + select ALLWINNER_A10_DRAMC select ALLWINNER_EMAC select SERIAL select UNIMP diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 86baeeeca2..a5f7a36ac9 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -25,6 +25,7 @@ #include "hw/boards.h" #include "hw/usb/hcd-ohci.h" =20 +#define AW_A10_DRAMC_BASE 0x01c01000 #define AW_A10_MMC0_BASE 0x01c0f000 #define AW_A10_CCM_BASE 0x01c20000 #define AW_A10_PIC_REG_BASE 0x01c20400 @@ -49,6 +50,8 @@ static void aw_a10_init(Object *obj) =20 object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM); =20 + object_initialize_child(obj, "dramc", &s->dramc, TYPE_AW_A10_DRAMC); + object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC); =20 object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI); @@ -110,6 +113,10 @@ static void aw_a10_realize(DeviceState *dev, Error **e= rrp) sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE); =20 + /* DRAM Control Module */ + sysbus_realize(SYS_BUS_DEVICE(&s->dramc), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->dramc), 0, AW_A10_DRAMC_BASE); + /* FIXME use qdev NIC properties instead of nd_table[] */ if (nd_table[0].used) { qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC); diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index ed07bf4133..052fb54310 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -177,4 +177,7 @@ config LASI config ALLWINNER_A10_CCM bool =20 +config ALLWINNER_A10_DRAMC + bool + source macio/Kconfig diff --git a/hw/misc/allwinner-a10-dramc.c b/hw/misc/allwinner-a10-dramc.c new file mode 100644 index 0000000000..e118b0c2fd --- /dev/null +++ b/hw/misc/allwinner-a10-dramc.c @@ -0,0 +1,179 @@ +/* + * Allwinner A10 DRAM Controller emulation + * + * Copyright (C) 2022 Strahinja Jankovic + * + * This file is derived from Allwinner H3 DRAMC, + * by Niek Linnenbank. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "hw/sysbus.h" +#include "migration/vmstate.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "hw/misc/allwinner-a10-dramc.h" + +/* DRAMC register offsets */ +enum { + REG_SDR_CCR =3D 0x0000, + REG_SDR_ZQCR0 =3D 0x00a8, + REG_SDR_ZQSR =3D 0x00b0 +}; + +#define REG_INDEX(offset) (offset / sizeof(uint32_t)) + +/* DRAMC register flags */ +enum { + REG_SDR_CCR_DATA_TRAINING =3D (1 << 30), + REG_SDR_CCR_DRAM_INIT =3D (1 << 31), +}; +enum { + REG_SDR_ZQSR_ZCAL =3D (1 << 31), +}; + +/* DRAMC register reset values */ +enum { + REG_SDR_CCR_RESET =3D 0x80020000, + REG_SDR_ZQCR0_RESET =3D 0x07b00000, + REG_SDR_ZQSR_RESET =3D 0x80000000 +}; + +static uint64_t allwinner_a10_dramc_read(void *opaque, hwaddr offset, + unsigned size) +{ + const AwA10DramControllerState *s =3D AW_A10_DRAMC(opaque); + const uint32_t idx =3D REG_INDEX(offset); + + switch (offset) { + case REG_SDR_CCR: + case REG_SDR_ZQCR0: + case REG_SDR_ZQSR: + break; + case 0x2e4 ... AW_A10_DRAMC_IOSIZE: + qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n", + __func__, (uint32_t)offset); + return 0; + default: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n", + __func__, (uint32_t)offset); + return 0; + } + + return s->regs[idx]; +} + +static void allwinner_a10_dramc_write(void *opaque, hwaddr offset, + uint64_t val, unsigned size) +{ + AwA10DramControllerState *s =3D AW_A10_DRAMC(opaque); + const uint32_t idx =3D REG_INDEX(offset); + + switch (offset) { + case REG_SDR_CCR: + if (val & REG_SDR_CCR_DRAM_INIT) { + /* Clear DRAM_INIT to indicate process is done. */ + val &=3D ~REG_SDR_CCR_DRAM_INIT; + } + if (val & REG_SDR_CCR_DATA_TRAINING) { + /* Clear DATA_TRAINING to indicate process is done. */ + val &=3D ~REG_SDR_CCR_DATA_TRAINING; + } + break; + case REG_SDR_ZQCR0: + /* Set ZCAL in ZQSR to indicate calibration is done. */ + s->regs[REG_INDEX(REG_SDR_ZQSR)] |=3D REG_SDR_ZQSR_ZCAL; + break; + case 0x2e4 ... AW_A10_DRAMC_IOSIZE: + qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n", + __func__, (uint32_t)offset); + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n", + __func__, (uint32_t)offset); + break; + } + + s->regs[idx] =3D (uint32_t) val; +} + +static const MemoryRegionOps allwinner_a10_dramc_ops =3D { + .read =3D allwinner_a10_dramc_read, + .write =3D allwinner_a10_dramc_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, + .impl.min_access_size =3D 4, +}; + +static void allwinner_a10_dramc_reset_enter(Object *obj, ResetType type) +{ + AwA10DramControllerState *s =3D AW_A10_DRAMC(obj); + + /* Set default values for registers */ + s->regs[REG_INDEX(REG_SDR_CCR)] =3D REG_SDR_CCR_RESET; + s->regs[REG_INDEX(REG_SDR_ZQCR0)] =3D REG_SDR_ZQCR0_RESET; + s->regs[REG_INDEX(REG_SDR_ZQSR)] =3D REG_SDR_ZQSR_RESET; +} + +static void allwinner_a10_dramc_init(Object *obj) +{ + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + AwA10DramControllerState *s =3D AW_A10_DRAMC(obj); + + /* Memory mapping */ + memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_dramc_ops, = s, + TYPE_AW_A10_DRAMC, AW_A10_DRAMC_IOSIZE); + sysbus_init_mmio(sbd, &s->iomem); +} + +static const VMStateDescription allwinner_a10_dramc_vmstate =3D { + .name =3D "allwinner-a10-dramc", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, AwA10DramControllerState, + AW_A10_DRAMC_REGS_NUM), + VMSTATE_END_OF_LIST() + } +}; + +static void allwinner_a10_dramc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + rc->phases.enter =3D allwinner_a10_dramc_reset_enter; + dc->vmsd =3D &allwinner_a10_dramc_vmstate; +} + +static const TypeInfo allwinner_a10_dramc_info =3D { + .name =3D TYPE_AW_A10_DRAMC, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_init =3D allwinner_a10_dramc_init, + .instance_size =3D sizeof(AwA10DramControllerState), + .class_init =3D allwinner_a10_dramc_class_init, +}; + +static void allwinner_a10_dramc_register(void) +{ + type_register_static(&allwinner_a10_dramc_info); +} + +type_init(allwinner_a10_dramc_register) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index c828dbeb26..9eaa0750b5 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -39,6 +39,7 @@ subdir('macio') softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c')) =20 softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_CCM', if_true: files('allwinner= -a10-ccm.c')) +softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_DRAMC', if_true: files('allwinn= er-a10-dramc.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-c= cu.c')) specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpu= cfg.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-d= ramc.c')) diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index 45d0fc2f7e..abe4ff7066 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -13,6 +13,7 @@ #include "hw/usb/hcd-ehci.h" #include "hw/rtc/allwinner-rtc.h" #include "hw/misc/allwinner-a10-ccm.h" +#include "hw/misc/allwinner-a10-dramc.h" =20 #include "target/arm/cpu.h" #include "qom/object.h" @@ -32,6 +33,7 @@ struct AwA10State { =20 ARMCPU cpu; AwA10ClockCtlState ccm; + AwA10DramControllerState dramc; AwA10PITState timer; AwA10PICState intc; AwEmacState emac; diff --git a/include/hw/misc/allwinner-a10-dramc.h b/include/hw/misc/allwin= ner-a10-dramc.h new file mode 100644 index 0000000000..b61fbecbe7 --- /dev/null +++ b/include/hw/misc/allwinner-a10-dramc.h @@ -0,0 +1,68 @@ +/* + * Allwinner A10 DRAM Controller emulation + * + * Copyright (C) 2022 Strahinja Jankovic + * + * This file is derived from Allwinner H3 DRAMC, + * by Niek Linnenbank. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HW_MISC_ALLWINNER_A10_DRAMC_H +#define HW_MISC_ALLWINNER_A10_DRAMC_H + +#include "qom/object.h" +#include "hw/sysbus.h" +#include "hw/register.h" + +/** + * @name Constants + * @{ + */ + +/** Size of register I/O address space used by DRAMC device */ +#define AW_A10_DRAMC_IOSIZE (0x1000) + +/** Total number of known registers */ +#define AW_A10_DRAMC_REGS_NUM (AW_A10_DRAMC_IOSIZE / sizeof(uint32_t)) + +/** @} */ + +/** + * @name Object model + * @{ + */ + +#define TYPE_AW_A10_DRAMC "allwinner-a10-dramc" +OBJECT_DECLARE_SIMPLE_TYPE(AwA10DramControllerState, AW_A10_DRAMC) + +/** @} */ + +/** + * Allwinner A10 DRAMC object instance state. + */ +struct AwA10DramControllerState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + /** Maps I/O registers in physical memory */ + MemoryRegion iomem; + + /** Array of hardware registers */ + uint32_t regs[AW_A10_DRAMC_REGS_NUM]; +}; + +#endif /* HW_MISC_ALLWINNER_A10_DRAMC_H */ --=20 2.30.2 From nobody Tue May 14 05:45:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1671398553; cv=none; d=zohomail.com; s=zohoarc; b=Mx709FoJjNvbvZ7tfn/HmJ+d+KLtLyHCuYu1HcYmEQ5Bs12A7b2oLc5jviTS/wFGR/BGPkhbudPF0ihS2pBTQxEN4xSG0sqAXI655VuuImnYngQmeeJDnhsavRxhMeJBiwfTpsW5VWjACSPgsCcUpLYcaZY1N4OBDrV6LmWEjmg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671398553; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=5qN77WgLj5OnfTKdt0NljZEP6GiDGqfSwDkYJIPIPiA=; b=ObR914OaTj7nKmR17FyMR2NCVedFWATm+V6EWAh7AsvboBeUWrdXA81YF+vPKfgdAP9g84h9D6d0WMecx8k1ULZjRL53Y7hq4pBbXi3hFC5WxZ4A9ZFUxNmSZnbQSewyIi3iOhUhdmvnXOOb+ND/UmDOtQsOHgT7q+PZcE6vnHU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671398553524733.2886115839437; Sun, 18 Dec 2022 13:22:33 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p714j-0001DW-AT; Sun, 18 Dec 2022 16:20:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p714G-000134-IN; Sun, 18 Dec 2022 16:19:45 -0500 Received: from mail-lf1-x12a.google.com ([2a00:1450:4864:20::12a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p714C-0001xa-2O; Sun, 18 Dec 2022 16:19:32 -0500 Received: by mail-lf1-x12a.google.com with SMTP id m29so10871212lfo.11; Sun, 18 Dec 2022 13:19:26 -0800 (PST) Received: from penguin.lxd (213-67-202-254-no43.tbcn.telia.com. [213.67.202.254]) by smtp.googlemail.com with ESMTPSA id w7-20020a05651234c700b0049464d89e40sm902620lfr.72.2022.12.18.13.19.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 13:19:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5qN77WgLj5OnfTKdt0NljZEP6GiDGqfSwDkYJIPIPiA=; b=ZjlS9u6IIedkvlo2pLdOZQjYZxx52LFdP0RAN5kdUXlLGNIWfpBDJZwASfKn/oIslk omJ5D0fFiJJpvPWCPeJU+3ho7Zm1LXtk4z/OIpvOkTggvMtzLXqaWPqjYmyoTnHF3Otl PD1nAFWe66gSfrqfR5vfXvuwMKmQXBld4CeHqyDzcW64OkwM8cwvS5o4HG0UHmZaaEKi N0PvajUGdTgu4Q6PtEodB8ltxgcee85A6dpd1fGaiJG8oyIL8TpDtmAZPiUP95yi8RGh WH8WQyPTEyC3N6qzP61J667WD2wZkWq52xiXniVnCfHScWn+DRzDSXoGp/MOPPPtWaqE ZzwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5qN77WgLj5OnfTKdt0NljZEP6GiDGqfSwDkYJIPIPiA=; b=L83Uyomgg7ifPlpDPVA/hEYwhZKAipI3a1H3leQeT1Fm2G6yg8eyBhcfr11SqVizFa 6gbUyEJoRNSPenWwRYxY51BwaH3YY+upMviOJs7Z9jY2pM9hru8sPkxOKjFcN4MdP3Nz 5W+KdYmdK97IYMd0P6RDwWwBV9l8uS+g4m9JOa74Eg4zAIO6GyxL/M4Add0Levkqz1qX iVzXxECMHdA0WtLgbWZDSEXq/EGtSW2dTksKY2j+qKFj632TJ4IiBdY/MBpDCbo9gkHM 58AN5KysJaAjO6fyTo0Cp4JokDmBDVe5RO0l1iH7KkqTbPxBtSZtklln8khrcLSPpQut dhPw== X-Gm-Message-State: ANoB5pkqojphumC87/xmQSOt03Ty2xnTlR0JPg9FJ651R/dRto1DOdxT JpWg2BgJWk+M89jF8jJlfYA= X-Google-Smtp-Source: AA0mqf7ne7Y6sb7a78QCS9TYzegqR+q//4NbkZDVyyponwmCGuuar6WY8Inh/I3TV03JLR6i2IwWrA== X-Received: by 2002:a05:6512:e9f:b0:4b5:a331:759b with SMTP id bi31-20020a0565120e9f00b004b5a331759bmr13479708lfb.5.1671398364786; Sun, 18 Dec 2022 13:19:24 -0800 (PST) From: Strahinja Jankovic X-Google-Original-From: Strahinja Jankovic To: Peter Maydell Cc: Beniamino Galvani , Niek Linnenbank , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Strahinja Jankovic Subject: [PATCH v2 3/7] hw/i2c: Allwinner TWI/I2C Emulation Date: Sun, 18 Dec 2022 22:19:14 +0100 Message-Id: <20221218211918.3592-4-strahinja.p.jankovic@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> References: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::12a; envelope-from=strahinjapjankovic@gmail.com; helo=mail-lf1-x12a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1671398555338100003 Content-Type: text/plain; charset="utf-8" This patch implements Allwinner TWI/I2C controller emulation. Only master-mode functionality is implemented. The SPL boot for Cubieboard expects AXP209 PMIC on TWI0/I2C0 bus, so this is first part enabling the TWI/I2C bus operation. Since both Allwinner A10 and H3 use the same module, it is added for both boards. Signed-off-by: Strahinja Jankovic --- hw/arm/Kconfig | 2 + hw/arm/allwinner-a10.c | 8 + hw/arm/allwinner-h3.c | 11 +- hw/i2c/Kconfig | 4 + hw/i2c/allwinner-i2c.c | 459 +++++++++++++++++++++++++++++++++ hw/i2c/meson.build | 1 + hw/i2c/trace-events | 5 + include/hw/arm/allwinner-a10.h | 2 + include/hw/arm/allwinner-h3.h | 3 + include/hw/i2c/allwinner-i2c.h | 55 ++++ 10 files changed, 549 insertions(+), 1 deletion(-) create mode 100644 hw/i2c/allwinner-i2c.c create mode 100644 include/hw/i2c/allwinner-i2c.h diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 140f142ae5..eefe1fd134 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -322,6 +322,7 @@ config ALLWINNER_A10 select ALLWINNER_A10_CCM select ALLWINNER_A10_DRAMC select ALLWINNER_EMAC + select ALLWINNER_I2C select SERIAL select UNIMP =20 @@ -329,6 +330,7 @@ config ALLWINNER_H3 bool select ALLWINNER_A10_PIT select ALLWINNER_SUN8I_EMAC + select ALLWINNER_I2C select SERIAL select ARM_TIMER select ARM_GIC diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index a5f7a36ac9..17e439777e 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -36,6 +36,7 @@ #define AW_A10_OHCI_BASE 0x01c14400 #define AW_A10_SATA_BASE 0x01c18000 #define AW_A10_RTC_BASE 0x01c20d00 +#define AW_A10_I2C0_BASE 0x01c2ac00 =20 static void aw_a10_init(Object *obj) { @@ -56,6 +57,8 @@ static void aw_a10_init(Object *obj) =20 object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI); =20 + object_initialize_child(obj, "i2c0", &s->i2c0, TYPE_AW_I2C); + if (machine_usb(current_machine)) { int i; =20 @@ -176,6 +179,11 @@ static void aw_a10_realize(DeviceState *dev, Error **e= rrp) /* RTC */ sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal); sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->rtc), 0, AW_A10_RTC_BASE, 1= 0); + + /* I2C */ + sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, AW_A10_I2C0_BASE); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, qdev_get_gpio_in(dev, = 7)); } =20 static void aw_a10_class_init(ObjectClass *oc, void *data) diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c index 308ed15552..bfce3c8d92 100644 --- a/hw/arm/allwinner-h3.c +++ b/hw/arm/allwinner-h3.c @@ -53,6 +53,7 @@ const hwaddr allwinner_h3_memmap[] =3D { [AW_H3_DEV_UART1] =3D 0x01c28400, [AW_H3_DEV_UART2] =3D 0x01c28800, [AW_H3_DEV_UART3] =3D 0x01c28c00, + [AW_H3_DEV_TWI0] =3D 0x01c2ac00, [AW_H3_DEV_EMAC] =3D 0x01c30000, [AW_H3_DEV_DRAMCOM] =3D 0x01c62000, [AW_H3_DEV_DRAMCTL] =3D 0x01c63000, @@ -106,7 +107,6 @@ struct AwH3Unimplemented { { "uart1", 0x01c28400, 1 * KiB }, { "uart2", 0x01c28800, 1 * KiB }, { "uart3", 0x01c28c00, 1 * KiB }, - { "twi0", 0x01c2ac00, 1 * KiB }, { "twi1", 0x01c2b000, 1 * KiB }, { "twi2", 0x01c2b400, 1 * KiB }, { "scr", 0x01c2c400, 1 * KiB }, @@ -150,6 +150,7 @@ enum { AW_H3_GIC_SPI_UART1 =3D 1, AW_H3_GIC_SPI_UART2 =3D 2, AW_H3_GIC_SPI_UART3 =3D 3, + AW_H3_GIC_SPI_TWI0 =3D 6, AW_H3_GIC_SPI_TIMER0 =3D 18, AW_H3_GIC_SPI_TIMER1 =3D 19, AW_H3_GIC_SPI_MMC0 =3D 60, @@ -225,6 +226,8 @@ static void allwinner_h3_init(Object *obj) "ram-size"); =20 object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN6I); + + object_initialize_child(obj, "twi0", &s->i2c0, TYPE_AW_I2C); } =20 static void allwinner_h3_realize(DeviceState *dev, Error **errp) @@ -423,6 +426,12 @@ static void allwinner_h3_realize(DeviceState *dev, Err= or **errp) sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, s->memmap[AW_H3_DEV_RTC]); =20 + /* I2C */ + sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, s->memmap[AW_H3_DEV_TWI0]= ); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, + qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_TWI= 0)); + /* Unimplemented devices */ for (i =3D 0; i < ARRAY_SIZE(unimplemented); i++) { create_unimplemented_device(unimplemented[i].device_name, diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig index 9bb8870517..f8ec461be3 100644 --- a/hw/i2c/Kconfig +++ b/hw/i2c/Kconfig @@ -34,6 +34,10 @@ config MPC_I2C bool select I2C =20 +config ALLWINNER_I2C + bool + select I2C + config PCA954X bool select I2C diff --git a/hw/i2c/allwinner-i2c.c b/hw/i2c/allwinner-i2c.c new file mode 100644 index 0000000000..a435965836 --- /dev/null +++ b/hw/i2c/allwinner-i2c.c @@ -0,0 +1,459 @@ +/* + * Allwinner I2C Bus Serial Interface Emulation + * + * Copyright (C) 2022 Strahinja Jankovic + * + * This file is derived from IMX I2C controller, + * by Jean-Christophe DUBOIS . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * SPDX-License-Identifier: MIT + */ + +#include "qemu/osdep.h" +#include "hw/i2c/allwinner-i2c.h" +#include "hw/irq.h" +#include "migration/vmstate.h" +#include "hw/i2c/i2c.h" +#include "qemu/log.h" +#include "trace.h" +#include "qemu/module.h" + +/* Allwinner I2C memory map */ +#define TWI_ADDR_REG 0x00 /* slave address register */ +#define TWI_XADDR_REG 0x04 /* extended slave address register */ +#define TWI_DATA_REG 0x08 /* data register */ +#define TWI_CNTR_REG 0x0c /* control register */ +#define TWI_STAT_REG 0x10 /* status register */ +#define TWI_CCR_REG 0x14 /* clock control register */ +#define TWI_SRST_REG 0x18 /* software reset register */ +#define TWI_EFR_REG 0x1c /* enhance feature register */ +#define TWI_LCR_REG 0x20 /* line control register */ + +/* Used only in slave mode, do not set */ +#define TWI_ADDR_RESET 0 +#define TWI_XADDR_RESET 0 + +/* Data register */ +#define TWI_DATA_MASK 0xFF +#define TWI_DATA_RESET 0 + +/* Control register */ +#define TWI_CNTR_INT_EN (1 << 7) +#define TWI_CNTR_BUS_EN (1 << 6) +#define TWI_CNTR_M_STA (1 << 5) +#define TWI_CNTR_M_STP (1 << 4) +#define TWI_CNTR_INT_FLAG (1 << 3) +#define TWI_CNTR_A_ACK (1 << 2) +#define TWI_CNTR_MASK 0xFC +#define TWI_CNTR_RESET 0 + +/* Status register */ +#define TWI_STAT_MASK 0xF8 +#define TWI_STAT_RESET 0xF8 + +/* Clock register */ +#define TWI_CCR_CLK_M_MASK 0x78 +#define TWI_CCR_CLK_N_MASK 0x07 +#define TWI_CCR_MASK 0x7F +#define TWI_CCR_RESET 0 + +/* Soft reset */ +#define TWI_SRST_MASK 0x01 +#define TWI_SRST_RESET 0 + +/* Enhance feature */ +#define TWI_EFR_MASK 0x03 +#define TWI_EFR_RESET 0 + +/* Line control */ +#define TWI_LCR_SCL_STATE (1 << 5) +#define TWI_LCR_SDA_STATE (1 << 4) +#define TWI_LCR_SCL_CTL (1 << 3) +#define TWI_LCR_SCL_CTL_EN (1 << 2) +#define TWI_LCR_SDA_CTL (1 << 1) +#define TWI_LCR_SDA_CTL_EN (1 << 0) +#define TWI_LCR_MASK 0x3F +#define TWI_LCR_RESET 0x3A + +/* Status value in STAT register is shifted by 3 bits */ +#define TWI_STAT_SHIFT 3 +#define STAT_FROM_STA(x) ((x) << TWI_STAT_SHIFT) +#define STAT_TO_STA(x) ((x) >> TWI_STAT_SHIFT) + +enum { + STAT_BUS_ERROR =3D 0, + /* Master mode */ + STAT_M_STA_TX, + STAT_M_RSTA_TX, + STAT_M_ADDR_WR_ACK, + STAT_M_ADDR_WR_NACK, + STAT_M_DATA_TX_ACK, + STAT_M_DATA_TX_NACK, + STAT_M_ARB_LOST, + STAT_M_ADDR_RD_ACK, + STAT_M_ADDR_RD_NACK, + STAT_M_DATA_RX_ACK, + STAT_M_DATA_RX_NACK, + /* Slave mode */ + STAT_S_ADDR_WR_ACK, + STAT_S_ARB_LOST_AW_ACK, + STAT_S_GCA_ACK, + STAT_S_ARB_LOST_GCA_ACK, + STAT_S_DATA_RX_SA_ACK, + STAT_S_DATA_RX_SA_NACK, + STAT_S_DATA_RX_GCA_ACK, + STAT_S_DATA_RX_GCA_NACK, + STAT_S_STP_RSTA, + STAT_S_ADDR_RD_ACK, + STAT_S_ARB_LOST_AR_ACK, + STAT_S_DATA_TX_ACK, + STAT_S_DATA_TX_NACK, + STAT_S_LB_TX_ACK, + /* Master mode, 10-bit */ + STAT_M_2ND_ADDR_WR_ACK, + STAT_M_2ND_ADDR_WR_NACK, + /* Idle */ + STAT_IDLE =3D 0x1f +} TWI_STAT_STA; + +static const char *allwinner_i2c_get_regname(unsigned offset) +{ + switch (offset) { + case TWI_ADDR_REG: + return "ADDR"; + case TWI_XADDR_REG: + return "XADDR"; + case TWI_DATA_REG: + return "DATA"; + case TWI_CNTR_REG: + return "CNTR"; + case TWI_STAT_REG: + return "STAT"; + case TWI_CCR_REG: + return "CCR"; + case TWI_SRST_REG: + return "SRST"; + case TWI_EFR_REG: + return "EFR"; + case TWI_LCR_REG: + return "LCR"; + default: + return "[?]"; + } +} + +static inline bool allwinner_i2c_is_reset(AWI2CState *s) +{ + return s->srst & TWI_SRST_MASK; +} + +static inline bool allwinner_i2c_bus_is_enabled(AWI2CState *s) +{ + return s->cntr & TWI_CNTR_BUS_EN; +} + +static inline bool allwinner_i2c_interrupt_is_enabled(AWI2CState *s) +{ + return s->cntr & TWI_CNTR_INT_EN; +} + +static void allwinner_i2c_reset_hold(Object *obj) +{ + AWI2CState *s =3D AW_I2C(obj); + + if (STAT_TO_STA(s->stat) !=3D STAT_IDLE) { + i2c_end_transfer(s->bus); + } + + s->addr =3D TWI_ADDR_RESET; + s->xaddr =3D TWI_XADDR_RESET; + s->data =3D TWI_DATA_RESET; + s->cntr =3D TWI_CNTR_RESET; + s->stat =3D TWI_STAT_RESET; + s->ccr =3D TWI_CCR_RESET; + s->srst =3D TWI_SRST_RESET; + s->efr =3D TWI_EFR_RESET; + s->lcr =3D TWI_LCR_RESET; +} + +static inline void allwinner_i2c_raise_interrupt(AWI2CState *s) +{ + /* + * Raise an interrupt if the device is not reset and it is configured + * to generate some interrupts. + */ + if (!allwinner_i2c_is_reset(s) && allwinner_i2c_bus_is_enabled(s)) { + if (STAT_TO_STA(s->stat) !=3D STAT_IDLE) { + s->cntr |=3D TWI_CNTR_INT_FLAG; + if (allwinner_i2c_interrupt_is_enabled(s)) { + qemu_irq_raise(s->irq); + } + } + } +} + +static uint64_t allwinner_i2c_read(void *opaque, hwaddr offset, + unsigned size) +{ + uint16_t value; + AWI2CState *s =3D AW_I2C(opaque); + + switch (offset) { + case TWI_ADDR_REG: + value =3D s->addr; + break; + case TWI_XADDR_REG: + value =3D s->xaddr; + break; + case TWI_DATA_REG: + if ((STAT_TO_STA(s->stat) =3D=3D STAT_M_ADDR_RD_ACK) || + (STAT_TO_STA(s->stat) =3D=3D STAT_M_DATA_RX_ACK) || + (STAT_TO_STA(s->stat) =3D=3D STAT_M_DATA_RX_NACK)) { + /* Get the next byte */ + s->data =3D i2c_recv(s->bus); + + if (s->cntr & TWI_CNTR_A_ACK) { + s->stat =3D STAT_FROM_STA(STAT_M_DATA_RX_ACK); + } else { + s->stat =3D STAT_FROM_STA(STAT_M_DATA_RX_NACK); + } + allwinner_i2c_raise_interrupt(s); + } + value =3D s->data; + break; + case TWI_CNTR_REG: + value =3D s->cntr; + break; + case TWI_STAT_REG: + value =3D s->stat; + /* + * If polling when reading then change state to indicate data + * is available + */ + if (STAT_TO_STA(s->stat) =3D=3D STAT_M_ADDR_RD_ACK) { + if (s->cntr & TWI_CNTR_A_ACK) { + s->stat =3D STAT_FROM_STA(STAT_M_DATA_RX_ACK); + } else { + s->stat =3D STAT_FROM_STA(STAT_M_DATA_RX_NACK); + } + allwinner_i2c_raise_interrupt(s); + } + break; + case TWI_CCR_REG: + value =3D s->ccr; + break; + case TWI_SRST_REG: + value =3D s->srst; + break; + case TWI_EFR_REG: + value =3D s->efr; + break; + case TWI_LCR_REG: + value =3D s->lcr; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%" + HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset); + value =3D 0; + break; + } + + trace_allwinner_i2c_read(allwinner_i2c_get_regname(offset), offset, va= lue); + + return (uint64_t)value; +} + +static void allwinner_i2c_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + AWI2CState *s =3D AW_I2C(opaque); + + value &=3D 0xff; + + trace_allwinner_i2c_write(allwinner_i2c_get_regname(offset), offset, v= alue); + + switch (offset) { + case TWI_ADDR_REG: + s->addr =3D (uint8_t)value; + break; + case TWI_XADDR_REG: + s->xaddr =3D (uint8_t)value; + break; + case TWI_DATA_REG: + /* If the device is in reset or not enabled, nothing to do */ + if (allwinner_i2c_is_reset(s) || (!allwinner_i2c_bus_is_enabled(s)= )) { + break; + } + + s->data =3D value & TWI_DATA_MASK; + + switch (STAT_TO_STA(s->stat)) { + case STAT_M_STA_TX: + case STAT_M_RSTA_TX: + /* Send address */ + if (i2c_start_transfer(s->bus, extract32(s->data, 1, 7), + extract32(s->data, 0, 1))) { + /* If non zero is returned, the address is not valid */ + s->stat =3D STAT_FROM_STA(STAT_M_ADDR_WR_NACK); + } else { + /* Determine if read of write */ + if (extract32(s->data, 0, 1)) { + s->stat =3D STAT_FROM_STA(STAT_M_ADDR_RD_ACK); + } else { + s->stat =3D STAT_FROM_STA(STAT_M_ADDR_WR_ACK); + } + allwinner_i2c_raise_interrupt(s); + } + break; + case STAT_M_ADDR_WR_ACK: + case STAT_M_DATA_TX_ACK: + if (i2c_send(s->bus, s->data)) { + /* If the target return non zero then end the transfer */ + s->stat =3D STAT_FROM_STA(STAT_M_DATA_TX_NACK); + i2c_end_transfer(s->bus); + } else { + s->stat =3D STAT_FROM_STA(STAT_M_DATA_TX_ACK); + allwinner_i2c_raise_interrupt(s); + } + break; + default: + break; + } + break; + case TWI_CNTR_REG: + if (!allwinner_i2c_is_reset(s)) { + /* Do something only if not in software reset */ + s->cntr =3D value & TWI_CNTR_MASK; + + /* Check if start condition should be sent */ + if (s->cntr & TWI_CNTR_M_STA) { + /* Update status */ + if (STAT_TO_STA(s->stat) =3D=3D STAT_IDLE) { + /* Send start condition */ + s->stat =3D STAT_FROM_STA(STAT_M_STA_TX); + } else { + /* Send repeated start condition */ + s->stat =3D STAT_FROM_STA(STAT_M_RSTA_TX); + } + /* Clear start condition */ + s->cntr &=3D ~TWI_CNTR_M_STA; + } + if (s->cntr & TWI_CNTR_M_STP) { + /* Update status */ + i2c_end_transfer(s->bus); + s->stat =3D STAT_FROM_STA(STAT_IDLE); + s->cntr &=3D ~TWI_CNTR_M_STP; + } + if ((s->cntr & TWI_CNTR_INT_FLAG) =3D=3D 0) { + /* Interrupt flag cleared */ + qemu_irq_lower(s->irq); + } + if ((s->cntr & TWI_CNTR_A_ACK) =3D=3D 0) { + if (STAT_TO_STA(s->stat) =3D=3D STAT_M_DATA_RX_ACK) { + s->stat =3D STAT_FROM_STA(STAT_M_DATA_RX_NACK); + } + } else { + if (STAT_TO_STA(s->stat) =3D=3D STAT_M_DATA_RX_NACK) { + s->stat =3D STAT_FROM_STA(STAT_M_DATA_RX_ACK); + } + } + allwinner_i2c_raise_interrupt(s); + + } + break; + case TWI_CCR_REG: + s->ccr =3D value & TWI_CCR_MASK; + break; + case TWI_SRST_REG: + if (((value & TWI_SRST_MASK) =3D=3D 0) && (s->srst & TWI_SRST_MASK= )) { + /* Perform reset */ + allwinner_i2c_reset_hold(OBJECT(s)); + } + s->srst =3D value & TWI_SRST_MASK; + break; + case TWI_EFR_REG: + s->efr =3D value & TWI_EFR_MASK; + break; + case TWI_LCR_REG: + s->lcr =3D value & TWI_LCR_MASK; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%" + HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset); + break; + } +} + +static const MemoryRegionOps allwinner_i2c_ops =3D { + .read =3D allwinner_i2c_read, + .write =3D allwinner_i2c_write, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 4, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + +static const VMStateDescription allwinner_i2c_vmstate =3D { + .name =3D TYPE_AW_I2C, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT8(addr, AWI2CState), + VMSTATE_UINT8(xaddr, AWI2CState), + VMSTATE_UINT8(data, AWI2CState), + VMSTATE_UINT8(cntr, AWI2CState), + VMSTATE_UINT8(ccr, AWI2CState), + VMSTATE_UINT8(srst, AWI2CState), + VMSTATE_UINT8(efr, AWI2CState), + VMSTATE_UINT8(lcr, AWI2CState), + VMSTATE_END_OF_LIST() + } +}; + +static void allwinner_i2c_realize(DeviceState *dev, Error **errp) +{ + AWI2CState *s =3D AW_I2C(dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_i2c_ops, s, + TYPE_AW_I2C, AW_I2C_MEM_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); + sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); + s->bus =3D i2c_init_bus(dev, "i2c"); +} + +static void allwinner_i2c_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + rc->phases.hold =3D allwinner_i2c_reset_hold; + dc->vmsd =3D &allwinner_i2c_vmstate; + dc->realize =3D allwinner_i2c_realize; + dc->desc =3D "Allwinner I2C Controller"; +} + +static const TypeInfo allwinner_i2c_type_info =3D { + .name =3D TYPE_AW_I2C, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(AWI2CState), + .class_init =3D allwinner_i2c_class_init, +}; + +static void allwinner_i2c_register_types(void) +{ + type_register_static(&allwinner_i2c_type_info); +} + +type_init(allwinner_i2c_register_types) diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build index d3df273251..7de7f2f540 100644 --- a/hw/i2c/meson.build +++ b/hw/i2c/meson.build @@ -8,6 +8,7 @@ i2c_ss.add(when: 'CONFIG_BITBANG_I2C', if_true: files('bitb= ang_i2c.c')) i2c_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_i2c.c')) i2c_ss.add(when: 'CONFIG_IMX_I2C', if_true: files('imx_i2c.c')) i2c_ss.add(when: 'CONFIG_MPC_I2C', if_true: files('mpc_i2c.c')) +i2c_ss.add(when: 'CONFIG_ALLWINNER_I2C', if_true: files('allwinner-i2c.c')) i2c_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('microbit_i2c.c')) i2c_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_smbus.c')) i2c_ss.add(when: 'CONFIG_SMBUS_EEPROM', if_true: files('smbus_eeprom.c')) diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events index af181d43ee..52dbd53a23 100644 --- a/hw/i2c/trace-events +++ b/hw/i2c/trace-events @@ -8,6 +8,11 @@ i2c_send_async(uint8_t address, uint8_t data) "send_async(= addr:0x%02x) data:0x%0 i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x" i2c_ack(void) "" =20 +# allwinner_i2c.c + +allwinner_i2c_read(const char* reg_name, uint64_t offset, uint64_t value) = "read %s [0x%" PRIx64 "]: -> 0x%" PRIx64 +allwinner_i2c_write(const char* reg_name, uint64_t offset, uint64_t value)= "write %s [0x%" PRIx64 "]: <- 0x%" PRIx64 + # aspeed_i2c.c =20 aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, ui= nt32_t intr_status) "handling cmd=3D0x%x %s count=3D%d intr=3D0x%x" diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index abe4ff7066..763935fca9 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -14,6 +14,7 @@ #include "hw/rtc/allwinner-rtc.h" #include "hw/misc/allwinner-a10-ccm.h" #include "hw/misc/allwinner-a10-dramc.h" +#include "hw/i2c/allwinner-i2c.h" =20 #include "target/arm/cpu.h" #include "qom/object.h" @@ -39,6 +40,7 @@ struct AwA10State { AwEmacState emac; AllwinnerAHCIState sata; AwSdHostState mmc0; + AWI2CState i2c0; AwRtcState rtc; MemoryRegion sram_a; EHCISysBusState ehci[AW_A10_NUM_USB]; diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h index 63025fb27c..1d7ce20589 100644 --- a/include/hw/arm/allwinner-h3.h +++ b/include/hw/arm/allwinner-h3.h @@ -47,6 +47,7 @@ #include "hw/sd/allwinner-sdhost.h" #include "hw/net/allwinner-sun8i-emac.h" #include "hw/rtc/allwinner-rtc.h" +#include "hw/i2c/allwinner-i2c.h" #include "target/arm/cpu.h" #include "sysemu/block-backend.h" =20 @@ -82,6 +83,7 @@ enum { AW_H3_DEV_UART2, AW_H3_DEV_UART3, AW_H3_DEV_EMAC, + AW_H3_DEV_TWI0, AW_H3_DEV_DRAMCOM, AW_H3_DEV_DRAMCTL, AW_H3_DEV_DRAMPHY, @@ -130,6 +132,7 @@ struct AwH3State { AwH3SysCtrlState sysctrl; AwSidState sid; AwSdHostState mmc0; + AWI2CState i2c0; AwSun8iEmacState emac; AwRtcState rtc; GICState gic; diff --git a/include/hw/i2c/allwinner-i2c.h b/include/hw/i2c/allwinner-i2c.h new file mode 100644 index 0000000000..4f378b86ba --- /dev/null +++ b/include/hw/i2c/allwinner-i2c.h @@ -0,0 +1,55 @@ +/* + * Allwinner I2C Bus Serial Interface registers definition + * + * Copyright (C) 2022 Strahinja Jankovic. + * + * This file is derived from IMX I2C controller, + * by Jean-Christophe DUBOIS . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#ifndef ALLWINNER_I2C_H +#define ALLWINNER_I2C_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_AW_I2C "allwinner.i2c" +OBJECT_DECLARE_SIMPLE_TYPE(AWI2CState, AW_I2C) + +#define AW_I2C_MEM_SIZE 0x24 + +struct AWI2CState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + I2CBus *bus; + qemu_irq irq; + + uint8_t addr; + uint8_t xaddr; + uint8_t data; + uint8_t cntr; + uint8_t stat; + uint8_t ccr; + uint8_t srst; + uint8_t efr; + uint8_t lcr; +}; + +#endif /* ALLWINNER_I2C_H */ --=20 2.30.2 From nobody Tue May 14 05:45:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1671398616; cv=none; d=zohomail.com; s=zohoarc; b=K7WxHBdx3x56EGak690rXesT5Ft8o1ceo54dlXNX8rHA5vz2k56vJpOp1Jybi7OBk7WDUoUS8QJdw9owu5pYTMr/p5CPhSMT6sMHgPyVoCpwzj2Wvjkws1tI6IJ3b26x514LAxOAOBCU8yD3RaPJX5Mj6irbEDYNszqjDzuqsKc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671398616; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0WR80a9kd83QzVZqp5sz4z3lr8i2vKKDJnEjFIjOvcE=; b=DpZ05Vtdhx7HPj34aDqfYLZJ0r84iysJec0F2g9jm9Iu79Jr/IjVrcjBJ/lS+ZkHHou/HOpsC+ov2Y/eMOy+/P0lazg+x+pYhLwVPybQEF02AkSvLc44VFzQZ3IR2EYQsLT8+dr9+HaDomu02SxW5j5kh0KrANiFLRSf9SZhVZE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671398616567854.8807521552922; Sun, 18 Dec 2022 13:23:36 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p714v-0001Mt-CQ; Sun, 18 Dec 2022 16:20:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p714E-00012k-E6; Sun, 18 Dec 2022 16:19:30 -0500 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p714C-0001xe-2c; Sun, 18 Dec 2022 16:19:30 -0500 Received: by mail-lf1-x12b.google.com with SMTP id bf43so11093585lfb.6; Sun, 18 Dec 2022 13:19:26 -0800 (PST) Received: from penguin.lxd (213-67-202-254-no43.tbcn.telia.com. [213.67.202.254]) by smtp.googlemail.com with ESMTPSA id w7-20020a05651234c700b0049464d89e40sm902620lfr.72.2022.12.18.13.19.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 13:19:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0WR80a9kd83QzVZqp5sz4z3lr8i2vKKDJnEjFIjOvcE=; b=daYDwfa2meezU6UbRzuLgV8pqghPXBwWw5g6K+1aXmP2G7RY0uO9DN43jUIWCb3N2I BHpg35aNPMH7iMR/G+Aw+9UMTySzWsyeN8IJ2cArrzPXLFBTLhzU3WPNwQvr9jSp5DAp uP0Z9/EtQMFgZ2eRHvF+E2S2mQvNDy/L79A5NYvOEIgp+CfKv24Vq50vphIGqaLSkS7p xEcdUv0oxjHkF3tv7Xec5eHzD700bzqOPix9BEBNLDGs4wkfN1GXDOOMDIjkv8il04VH HAFgmklnujnFxa0gb/Z6mByLnaz9Feae2lqM5AkeUJkpGw7BNrRHRdhiXiMUu1A+QmrP 9ttA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0WR80a9kd83QzVZqp5sz4z3lr8i2vKKDJnEjFIjOvcE=; b=QkFkJ89MKGn03W8U0oaxinzidH+csR6+VfHSSchjQtggXiknlSxDpapICXTZv910LI qpV67CyTTsH+LaQD/3cdRn5nH/NW65rsBDP574bxpxvD3ku/HiWPOgWWT2TxqHMG/tlG JJTFM3xX6IEjINDmNRYT0T5pL7XWCeAN1MTefOrFqkSES1gIHfcWtQrtGmHcw3O+fumY qQ6+lfK3Ue4+sQBZdM9p6LkSOCXe9qOTajfz9M9LlMfSHFkyPIJC3B651wE5ZOHVQgtK Z+ZTXzeLEK8Par1EaMFE42SWd1fBzS9lG0XjhyP1g7+DmPShb46eM17R1+VH9wnSdxve S3vw== X-Gm-Message-State: ANoB5pk+b8QJ8GsfXGCp7tLv/R/QMUE95JixWFJ153t2jfUYJppSAMjE B1WIlVH8rd8xpxM8HXbs5fiw0QT1/JYxUvF6 X-Google-Smtp-Source: AA0mqf7HjGPt+qU/V2+B+nMXzi3DBipadjxUHnTlMfR/V69K9WEvxGQw1I6IOoQDiQfevZoMGz0TvA== X-Received: by 2002:a05:6512:304b:b0:4b5:892:3987 with SMTP id b11-20020a056512304b00b004b508923987mr22607876lfb.9.1671398365342; Sun, 18 Dec 2022 13:19:25 -0800 (PST) From: Strahinja Jankovic X-Google-Original-From: Strahinja Jankovic To: Peter Maydell Cc: Beniamino Galvani , Niek Linnenbank , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Strahinja Jankovic Subject: [PATCH v2 4/7] hw/misc: Allwinner AXP-209 Emulation Date: Sun, 18 Dec 2022 22:19:15 +0100 Message-Id: <20221218211918.3592-5-strahinja.p.jankovic@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> References: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::12b; envelope-from=strahinjapjankovic@gmail.com; helo=mail-lf1-x12b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1671398617594100003 Content-Type: text/plain; charset="utf-8" This patch adds minimal support for AXP-209 PMU. Most important is chip ID since U-Boot SPL expects version 0x1. Besides the chip ID register, reset values for two more registers used by A10 U-Boot SPL are covered. Signed-off-by: Strahinja Jankovic --- hw/arm/Kconfig | 1 + hw/misc/Kconfig | 4 + hw/misc/allwinner-axp-209.c | 238 ++++++++++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + hw/misc/trace-events | 5 + 5 files changed, 249 insertions(+) create mode 100644 hw/misc/allwinner-axp-209.c diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index eefe1fd134..67c6e83fe6 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -323,6 +323,7 @@ config ALLWINNER_A10 select ALLWINNER_A10_DRAMC select ALLWINNER_EMAC select ALLWINNER_I2C + select ALLWINNER_AXP_209 select SERIAL select UNIMP =20 diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 052fb54310..3855d937fd 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -180,4 +180,8 @@ config ALLWINNER_A10_CCM config ALLWINNER_A10_DRAMC bool =20 +config ALLWINNER_AXP_209 + bool + depends on I2C + source macio/Kconfig diff --git a/hw/misc/allwinner-axp-209.c b/hw/misc/allwinner-axp-209.c new file mode 100644 index 0000000000..cf79175034 --- /dev/null +++ b/hw/misc/allwinner-axp-209.c @@ -0,0 +1,238 @@ +/* + * AXP-209 Emulation + * + * Copyright (C) 2022 Strahinja Jankovic + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software= "), + * to deal in the Software without restriction, including without limitati= on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "trace.h" +#include "hw/i2c/i2c.h" +#include "migration/vmstate.h" + +#define TYPE_AXP_209 "allwinner.axp209" + +#define AXP_209(obj) \ + OBJECT_CHECK(AXP209I2CState, (obj), TYPE_AXP_209) + +/* registers */ +enum { + REG_POWER_STATUS =3D 0x0u, + REG_OPERATING_MODE, + REG_OTG_VBUS_STATUS, + REG_CHIP_VERSION, + REG_DATA_CACHE_0, + REG_DATA_CACHE_1, + REG_DATA_CACHE_2, + REG_DATA_CACHE_3, + REG_DATA_CACHE_4, + REG_DATA_CACHE_5, + REG_DATA_CACHE_6, + REG_DATA_CACHE_7, + REG_DATA_CACHE_8, + REG_DATA_CACHE_9, + REG_DATA_CACHE_A, + REG_DATA_CACHE_B, + REG_POWER_OUTPUT_CTRL =3D 0x12u, + REG_DC_DC2_OUT_V_CTRL =3D 0x23u, + REG_DC_DC2_DVS_CTRL =3D 0x25u, + REG_DC_DC3_OUT_V_CTRL =3D 0x27u, + REG_LDO2_4_OUT_V_CTRL, + REG_LDO3_OUT_V_CTRL, + REG_VBUS_CH_MGMT =3D 0x30u, + REG_SHUTDOWN_V_CTRL, + REG_SHUTDOWN_CTRL, + REG_CHARGE_CTRL_1, + REG_CHARGE_CTRL_2, + REG_SPARE_CHARGE_CTRL, + REG_PEK_KEY_CTRL, + REG_DC_DC_FREQ_SET, + REG_CHR_TEMP_TH_SET, + REG_CHR_HIGH_TEMP_TH_CTRL, + REG_IPSOUT_WARN_L1, + REG_IPSOUT_WARN_L2, + REG_DISCHR_TEMP_TH_SET, + REG_DISCHR_HIGH_TEMP_TH_CTRL, + REG_IRQ_BANK_1_CTRL =3D 0x40u, + REG_IRQ_BANK_2_CTRL, + REG_IRQ_BANK_3_CTRL, + REG_IRQ_BANK_4_CTRL, + REG_IRQ_BANK_5_CTRL, + REG_IRQ_BANK_1_STAT =3D 0x48u, + REG_IRQ_BANK_2_STAT, + REG_IRQ_BANK_3_STAT, + REG_IRQ_BANK_4_STAT, + REG_IRQ_BANK_5_STAT, + REG_ADC_ACIN_V_H =3D 0x56u, + REG_ADC_ACIN_V_L, + REG_ADC_ACIN_CURR_H, + REG_ADC_ACIN_CURR_L, + REG_ADC_VBUS_V_H, + REG_ADC_VBUS_V_L, + REG_ADC_VBUS_CURR_H, + REG_ADC_VBUS_CURR_L, + REG_ADC_INT_TEMP_H, + REG_ADC_INT_TEMP_L, + REG_ADC_TEMP_SENS_V_H =3D 0x62u, + REG_ADC_TEMP_SENS_V_L, + REG_ADC_BAT_V_H =3D 0x78u, + REG_ADC_BAT_V_L, + REG_ADC_BAT_DISCHR_CURR_H, + REG_ADC_BAT_DISCHR_CURR_L, + REG_ADC_BAT_CHR_CURR_H, + REG_ADC_BAT_CHR_CURR_L, + REG_ADC_IPSOUT_V_H, + REG_ADC_IPSOUT_V_L, + REG_DC_DC_MOD_SEL =3D 0x80u, + REG_ADC_EN_1, + REG_ADC_EN_2, + REG_ADC_SR_CTRL, + REG_ADC_IN_RANGE, + REG_GPIO1_ADC_IRQ_RISING_TH, + REG_GPIO1_ADC_IRQ_FALLING_TH, + REG_TIMER_CTRL =3D 0x8au, + REG_VBUS_CTRL_MON_SRP, + REG_OVER_TEMP_SHUTDOWN =3D 0x8fu, + REG_GPIO0_FEAT_SET, + REG_GPIO_OUT_HIGH_SET, + REG_GPIO1_FEAT_SET, + REG_GPIO2_FEAT_SET, + REG_GPIO_SIG_STATE_SET_MON, + REG_GPIO3_SET, + REG_COULOMB_CNTR_CTRL =3D 0xb8u, + REG_POWER_MEAS_RES, + NR_REGS +}; + +#define AXP_209_CHIP_VERSION_ID (0x01) +#define AXP_209_DC_DC2_OUT_V_CTRL_RESET (0x16) +#define AXP_209_IRQ_BANK_1_CTRL_RESET (0xd8) + +/* A simple I2C slave which returns values of ID or CNT register. */ +typedef struct AXP209I2CState { + /*< private >*/ + I2CSlave i2c; + /*< public >*/ + uint8_t regs[NR_REGS]; /* peripheral registers */ + uint8_t ptr; /* current register index */ + uint8_t count; /* counter used for tx/rx */ +} AXP209I2CState; + +/* Reset all counters and load ID register */ +static void axp_209_reset_enter(Object *obj, ResetType type) +{ + AXP209I2CState *s =3D AXP_209(obj); + + memset(s->regs, 0, NR_REGS); + s->ptr =3D 0; + s->count =3D 0; + s->regs[REG_CHIP_VERSION] =3D AXP_209_CHIP_VERSION_ID; + s->regs[REG_DC_DC2_OUT_V_CTRL] =3D AXP_209_DC_DC2_OUT_V_CTRL_RESET; + s->regs[REG_IRQ_BANK_1_CTRL] =3D AXP_209_IRQ_BANK_1_CTRL_RESET; +} + +/* Handle events from master. */ +static int axp_209_event(I2CSlave *i2c, enum i2c_event event) +{ + AXP209I2CState *s =3D AXP_209(i2c); + + s->count =3D 0; + + return 0; +} + +/* Called when master requests read */ +static uint8_t axp_209_rx(I2CSlave *i2c) +{ + AXP209I2CState *s =3D AXP_209(i2c); + uint8_t ret =3D 0xff; + + if (s->ptr < NR_REGS) { + ret =3D s->regs[s->ptr++]; + } + + trace_allwinner_axp_209_rx(s->ptr - 1, ret); + + return ret; +} + +/* + * Called when master sends write. + * Update ptr with byte 0, then perform write with second byte. + */ +static int axp_209_tx(I2CSlave *i2c, uint8_t data) +{ + AXP209I2CState *s =3D AXP_209(i2c); + + if (s->count =3D=3D 0) { + /* Store register address */ + s->ptr =3D data; + s->count++; + trace_allwinner_axp_209_select(data); + } else { + trace_allwinner_axp_209_tx(s->ptr, data); + if (s->ptr =3D=3D REG_DC_DC2_OUT_V_CTRL) { + s->regs[s->ptr++] =3D data; + } + } + + return 0; +} + +static const VMStateDescription vmstate_axp_209 =3D { + .name =3D TYPE_AXP_209, + .version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT8_ARRAY(regs, AXP209I2CState, NR_REGS), + VMSTATE_UINT8(count, AXP209I2CState), + VMSTATE_UINT8(ptr, AXP209I2CState), + VMSTATE_END_OF_LIST() + } +}; + +static void axp_209_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + I2CSlaveClass *isc =3D I2C_SLAVE_CLASS(oc); + ResettableClass *rc =3D RESETTABLE_CLASS(oc); + + rc->phases.enter =3D axp_209_reset_enter; + dc->vmsd =3D &vmstate_axp_209; + isc->event =3D axp_209_event; + isc->recv =3D axp_209_rx; + isc->send =3D axp_209_tx; +} + +static const TypeInfo axp_209_info =3D { + .name =3D TYPE_AXP_209, + .parent =3D TYPE_I2C_SLAVE, + .instance_size =3D sizeof(AXP209I2CState), + .class_init =3D axp_209_class_init +}; + +static void axp_209_register_devices(void) +{ + type_register_static(&axp_209_info); +} + +type_init(axp_209_register_devices); diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 9eaa0750b5..7d332851cb 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -40,6 +40,7 @@ softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: fi= les('ivshmem.c')) =20 softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_CCM', if_true: files('allwinner= -a10-ccm.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_DRAMC', if_true: files('allwinn= er-a10-dramc.c')) +softmmu_ss.add(when: 'CONFIG_ALLWINNER_AXP_209', if_true: files('allwinner= -axp-209.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-c= cu.c')) specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpu= cfg.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-d= ramc.c')) diff --git a/hw/misc/trace-events b/hw/misc/trace-events index c18bc0605e..f6a7a6901f 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -1,5 +1,10 @@ # See docs/devel/tracing.rst for syntax documentation. =20 +# allwinner-axp209.c +allwinner_axp_209_rx(uint8_t reg, uint8_t data) "Read reg 0x%" PRIx8 " : 0= x%" PRIx8 +allwinner_axp_209_select(uint8_t reg) "Accessing reg 0x%" PRIx8 +allwinner_axp_209_tx(uint8_t reg, uint8_t data) "Write reg 0x%" PRIx8 " : = 0x%" PRIx8 + # allwinner-cpucfg.c allwinner_cpucfg_cpu_reset(uint8_t cpu_id, uint32_t reset_addr) "id %u, re= set_addr 0x%" PRIx32 allwinner_cpucfg_read(uint64_t offset, uint64_t data, unsigned size) "offs= et 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32 --=20 2.30.2 From nobody Tue May 14 05:45:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1671398557; cv=none; d=zohomail.com; s=zohoarc; b=NlMqbYiYIMWyOBwj7RLDKRtzWLBx+E/p2T8LsM4GOkqK9x1alZuoIdtgdPiVVePwvLTD43zULt3g30ZOn7lRu6mCeZHMnB+x8Wm6xqWkPV0xuwdVEmRpmlEr7JJ8Fx8qBOah78SlPkL5JKT/4j07M1+IHTXsx6B/yjBOVdsrsbE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671398557; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=hNBvOLNtuNzW6P6rPNag+NZ5QBlW2U7hfyBqq0mBtpM=; b=YlEtFG30ion/BetK9BEXCTuTombB6RSZsJb2jeM/mQh3BhtPr/xRKYHyuYLId+iR0gBQz3YUOsUvPzlZ8DhiRy0Uh01ohD+5Gsj7blJEU2uLIj7n3MK5V6RdjYfcZtguNy2G7DUDbBzJ749xqF/2FRVrj7pz0jC72xdipe+wdyM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671398557146458.1728409285133; Sun, 18 Dec 2022 13:22:37 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p714w-0001PT-Ky; Sun, 18 Dec 2022 16:20:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p714F-000131-Qs; Sun, 18 Dec 2022 16:19:45 -0500 Received: from mail-lj1-x234.google.com ([2a00:1450:4864:20::234]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p714C-0001xp-Nv; Sun, 18 Dec 2022 16:19:31 -0500 Received: by mail-lj1-x234.google.com with SMTP id g14so7315269ljh.10; Sun, 18 Dec 2022 13:19:27 -0800 (PST) Received: from penguin.lxd (213-67-202-254-no43.tbcn.telia.com. [213.67.202.254]) by smtp.googlemail.com with ESMTPSA id w7-20020a05651234c700b0049464d89e40sm902620lfr.72.2022.12.18.13.19.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 13:19:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hNBvOLNtuNzW6P6rPNag+NZ5QBlW2U7hfyBqq0mBtpM=; b=eY4fzNfgP6QVix9ywq5T6WMc08Hb7EufgXpxVkd7j3TWsJAXzopeJs5GBIBffhbMUO BGVjDw0zDURnjLpT4gLNddSfvpvqMXuTRXkXWdqn4YFErcCumEOLrt3Um83U/Xxg/1Lr ysUWGyR6mZRwuQ8FDkQyVzGYpAPeQyrIvr4TQ22TXi7BVNPmQHzqEHCxBcGvEsNJXFwa 3152Dby7fES4Pzc/veBpata3U1tY/w8LDmUVyC0uRv0qJzaYKUDdSKibVE+32K+3tNwu IwDcNl8wIbMdtBSVmqzaQA9l3qlDFD27UELV6Xm4edhT/8uuyzWaWXzIkAjD6gegIBdp 5ZhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hNBvOLNtuNzW6P6rPNag+NZ5QBlW2U7hfyBqq0mBtpM=; b=7iUF3ryVSKhqsR4YdnCXKYLTu9cxRmqOVu0Y5NxBaPTfBf2oLHxFsFJ30809QD/oyR zJFBF6g4YSwAh3qh3v1eY3VmogcV/NqNv9KBSdFZ/L5kKIseinpxUjmRZSXc6ldXvA8E jPzHzVpCt2FW4ShHHwj4+pzFJspKFPXvmjUgixxwcsEAtka7RBzeNvV+514iZZ2fmovB bT4sFum5XCaTyTWN7c0P0MdAZH1XZYdemV0DA8M12717JTGEXpw3YtDi+KYa5Hoe/fSE Iis5QzveRUPWAa8DqECVCkg7cKs+vC0hCnbMgeRsdUMDkzRIwXbkvE+tmWI/6HRcSr/g O8Ww== X-Gm-Message-State: ANoB5pk+qkzAGnVPwYCpbP0besG2SxvTSPd1IxmUDTDI6Z2rr0rOGeRI t1F5JjdbOL8j2FsAOGe7+EY= X-Google-Smtp-Source: AA0mqf5FpPXEXHcPuC18ORXdy1QkF/Qs6qy1fqjebsnR094h3PGeGQ7Xdx2CgqovNZWQaWNYpLuIBw== X-Received: by 2002:a05:651c:1592:b0:26f:db35:d203 with SMTP id h18-20020a05651c159200b0026fdb35d203mr10202779ljq.15.1671398366104; Sun, 18 Dec 2022 13:19:26 -0800 (PST) From: Strahinja Jankovic X-Google-Original-From: Strahinja Jankovic To: Peter Maydell Cc: Beniamino Galvani , Niek Linnenbank , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Strahinja Jankovic Subject: [PATCH v2 5/7] hw/arm: Add AXP-209 to Cubieboard Date: Sun, 18 Dec 2022 22:19:16 +0100 Message-Id: <20221218211918.3592-6-strahinja.p.jankovic@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> References: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::234; envelope-from=strahinjapjankovic@gmail.com; helo=mail-lj1-x234.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1671398557391100001 Content-Type: text/plain; charset="utf-8" SPL Boot for Cubieboard expects AXP-209 connected to I2C0 bus. Signed-off-by: Strahinja Jankovic Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/arm/cubieboard.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index 5e3372a3c7..afc7980414 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -20,6 +20,7 @@ #include "hw/boards.h" #include "hw/qdev-properties.h" #include "hw/arm/allwinner-a10.h" +#include "hw/i2c/i2c.h" =20 static struct arm_boot_info cubieboard_binfo =3D { .loader_start =3D AW_A10_SDRAM_BASE, @@ -34,6 +35,7 @@ static void cubieboard_init(MachineState *machine) BlockBackend *blk; BusState *bus; DeviceState *carddev; + I2CBus *i2c; =20 /* BIOS is not supported by this board */ if (machine->firmware) { @@ -80,6 +82,10 @@ static void cubieboard_init(MachineState *machine) exit(1); } =20 + /* Connect AXP 209 */ + i2c =3D (I2CBus *)qdev_get_child_bus(DEVICE(&a10->i2c0), "i2c"); + i2c_slave_create_simple(i2c, "allwinner.axp209", 0x34); + /* Retrieve SD bus */ di =3D drive_get(IF_SD, 0, 0); blk =3D di ? blk_by_legacy_dinfo(di) : NULL; --=20 2.30.2 From nobody Tue May 14 05:45:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1671398525; cv=none; d=zohomail.com; s=zohoarc; b=QCvMMd5ZwNwK6Ld/Tj0Yg5DRRVfa1NLZcgqkpubL/H3EIJm0p4Zcdw2TFzj1YwuoCOOrkvgj32OYSxHEarKd4GDI+iw4s5dvc4wYE10PIpFiux+PDfRPLjumMnqyW8EOTe4PkKOta3Zcs2VKvZirR4Sv46chugr/AjiLiOznBO0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671398525; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=c08hVl9D9/u/T28Fz+sqopcOehEP0Ikwgs0RHn7FUE4=; b=VsrfFQv4vxiYRR21xez2UkeZh/jwrgnPZdFY6LXZmvlUNg8SNzZaOWh5adkBSAqCREHMbWI/a26iyoNh6BT0m/1S6z3oMX53Hqi1g4cl+ErLbrsHKIYwqwIzJscibpcOqQbfgPy3lox6kk5z9d/ND7pp53+mw0kAEg2DeX9bIDE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671398525467837.1394502514456; Sun, 18 Dec 2022 13:22:05 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p714w-0001PW-MX; Sun, 18 Dec 2022 16:20:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p714F-000132-Qy; Sun, 18 Dec 2022 16:19:45 -0500 Received: from mail-lf1-x135.google.com ([2a00:1450:4864:20::135]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p714C-0001xu-QC; Sun, 18 Dec 2022 16:19:31 -0500 Received: by mail-lf1-x135.google.com with SMTP id cf42so11132339lfb.1; Sun, 18 Dec 2022 13:19:27 -0800 (PST) Received: from penguin.lxd (213-67-202-254-no43.tbcn.telia.com. [213.67.202.254]) by smtp.googlemail.com with ESMTPSA id w7-20020a05651234c700b0049464d89e40sm902620lfr.72.2022.12.18.13.19.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 13:19:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=c08hVl9D9/u/T28Fz+sqopcOehEP0Ikwgs0RHn7FUE4=; b=i2att2n0VwJ/3bKuHh8FH1yazM93JCE0oN6KSYqmvj6Cz9Gj611BMt8spLu3Y12KXF cPp/S/v/NOL6jXJI8ruawtnYPdTXUXyenZUo1g4x6TAKHgUyEUdHn7f2b6Mc+tqN3HbU LU0d3aLUVvR8n7jiscE36RCBbvZxNtK/vfcf0I1321iJG0XtFUAuoUdYjexMt1/qL83/ FOd/HEhIGy9YsBZOtXzMP8OzLADMKgOOxSfCW/kW8mWDrfgAqHtUGeJ7OcyieFJRDPsh MqsaeUFjYHhkNTmZtUUfkWmI5rQKbheH9S+dIIFc6hDQkq/R1K5zKYvAs6YTNl+A4J1P 9dNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=c08hVl9D9/u/T28Fz+sqopcOehEP0Ikwgs0RHn7FUE4=; b=QA6UNfs0Oz7oSW+CEWBzrWFRPgJ1tOfgFwTLPww/lcQJmHuUzFjXQcIfVoN7lJI+cG K03iM+FOyiL2YvusPltSv1GzfsP1CLBuO/4HjSGE9JDybdi3/HgJwjQ0NdlHIpmLd1HW /QjaC2oliL8Sctzdh8mtdnx+LNcMWiUW+9Foa27mT4zRY5/wexuBGqOLXYzf4WIBLiuM ydgDvCNxMVFO3tolRZXSfl/QVe/l7RM0FHUdTYqIBWuR6soMThrEMnGlbdprONywPAMH ggADAeNOEojboM3L25caGsUPeq0TOS8FH1bbcsm6Zfc6IoIDRsT4MhXXLhFKulYateII WiKw== X-Gm-Message-State: ANoB5pnCfJfyIu771Yh/VPn1tfXzCMO4wQPn0XcehFAH7JGXXJZosjL2 g/faCWPwJE92wQfu2ZP3A6wIN126Uw3qZA08 X-Google-Smtp-Source: AA0mqf7y5TuS4sZBgSUoJKgbKm+06bRy6oQEVkQWRf79FkFRfJYO2bTUxQn6w3xrvUPx6ZeDR+/sFw== X-Received: by 2002:a05:6512:de:b0:4b5:2ef3:fd2a with SMTP id c30-20020a05651200de00b004b52ef3fd2amr16845051lfp.47.1671398366785; Sun, 18 Dec 2022 13:19:26 -0800 (PST) From: Strahinja Jankovic X-Google-Original-From: Strahinja Jankovic To: Peter Maydell Cc: Beniamino Galvani , Niek Linnenbank , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Strahinja Jankovic Subject: [PATCH v2 6/7] hw/arm: Allwinner A10 enable SPL load from MMC Date: Sun, 18 Dec 2022 22:19:17 +0100 Message-Id: <20221218211918.3592-7-strahinja.p.jankovic@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> References: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::135; envelope-from=strahinjapjankovic@gmail.com; helo=mail-lf1-x135.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1671398527234100003 Content-Type: text/plain; charset="utf-8" This patch enables copying of SPL from MMC if `-kernel` parameter is not passed when starting QEMU. SPL is copied to SRAM_A. The approach is reused from Allwinner H3 implementation. Tested with Armbian and custom Yocto image. Signed-off-by: Strahinja Jankovic Reviewed-by: Niek Linnenbank --- hw/arm/allwinner-a10.c | 18 ++++++++++++++++++ hw/arm/cubieboard.c | 5 +++++ include/hw/arm/allwinner-a10.h | 21 +++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 17e439777e..dc1966ff7a 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -24,7 +24,9 @@ #include "sysemu/sysemu.h" #include "hw/boards.h" #include "hw/usb/hcd-ohci.h" +#include "hw/loader.h" =20 +#define AW_A10_SRAM_A_BASE 0x00000000 #define AW_A10_DRAMC_BASE 0x01c01000 #define AW_A10_MMC0_BASE 0x01c0f000 #define AW_A10_CCM_BASE 0x01c20000 @@ -38,6 +40,22 @@ #define AW_A10_RTC_BASE 0x01c20d00 #define AW_A10_I2C0_BASE 0x01c2ac00 =20 +void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk) +{ + const int64_t rom_size =3D 32 * KiB; + g_autofree uint8_t *buffer =3D g_new0(uint8_t, rom_size); + + if (blk_pread(blk, 8 * KiB, rom_size, buffer, 0) < 0) { + error_setg(&error_fatal, "%s: failed to read BlockBackend data", + __func__); + return; + } + + rom_add_blob("allwinner-a10.bootrom", buffer, rom_size, + rom_size, AW_A10_SRAM_A_BASE, + NULL, NULL, NULL, NULL, false); +} + static void aw_a10_init(Object *obj) { AwA10State *s =3D AW_A10(obj); diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index afc7980414..37659c35fd 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -99,6 +99,11 @@ static void cubieboard_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE, machine->ram); =20 + /* Load target kernel or start using BootROM */ + if (!machine->kernel_filename && blk && blk_is_available(blk)) { + /* Use Boot ROM to copy data from SD card to SRAM */ + allwinner_a10_bootrom_setup(a10, blk); + } /* TODO create and connect IDE devices for ide_drive_get() */ =20 cubieboard_binfo.ram_size =3D machine->ram_size; diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index 763935fca9..b3c9ed24c7 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -15,6 +15,7 @@ #include "hw/misc/allwinner-a10-ccm.h" #include "hw/misc/allwinner-a10-dramc.h" #include "hw/i2c/allwinner-i2c.h" +#include "sysemu/block-backend.h" =20 #include "target/arm/cpu.h" #include "qom/object.h" @@ -47,4 +48,24 @@ struct AwA10State { OHCISysBusState ohci[AW_A10_NUM_USB]; }; =20 +/** + * Emulate Boot ROM firmware setup functionality. + * + * A real Allwinner A10 SoC contains a Boot ROM + * which is the first code that runs right after + * the SoC is powered on. The Boot ROM is responsible + * for loading user code (e.g. a bootloader) from any + * of the supported external devices and writing the + * downloaded code to internal SRAM. After loading the SoC + * begins executing the code written to SRAM. + * + * This function emulates the Boot ROM by copying 32 KiB + * of data from the given block device and writes it to + * the start of the first internal SRAM memory. + * + * @s: Allwinner A10 state object pointer + * @blk: Block backend device object pointer + */ +void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk); + #endif --=20 2.30.2 From nobody Tue May 14 05:45:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1671398478; cv=none; d=zohomail.com; s=zohoarc; b=lMbzC71FrxSXGfuOo7yQ2Q0lSsUNBVklb/czUZTqZ3OAjYlsRg9WVPhMk4wNAE7K4J6dQDByFTaZFqzp02fBFxoUIcd+DhY04adpPulH42djrYDSW45c7eEjMlE/AcuPNkEWRO5wYEAyxE2nv6tetCPvKiARyvbY6g9eDJNxo/o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671398478; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=46C2MF6RZfVqrMZvxDPCl1p+Oawy3L4vspnUr+kuxSg=; b=SQASzKrWpGFmr84hcJQW9GkdzInrbxMM+NowNMmrM+xCkuTQA4nRQkmY10ras6fMwwuUYZfIhDnAZyOOXGtZlki0kRc1PqvaWdf0b2HGcYTqNNn/iwXoair2Om34ET2NdVI429Oliqee6Xi7tcGRdg/CynbSf/UZHRrXGR3fEQs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167139847867470.54053321825779; Sun, 18 Dec 2022 13:21:18 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p714g-00018S-LQ; Sun, 18 Dec 2022 16:19:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p714F-000133-W3; Sun, 18 Dec 2022 16:19:45 -0500 Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p714D-0001yF-UQ; Sun, 18 Dec 2022 16:19:31 -0500 Received: by mail-lf1-x129.google.com with SMTP id bp15so11053242lfb.13; Sun, 18 Dec 2022 13:19:28 -0800 (PST) Received: from penguin.lxd (213-67-202-254-no43.tbcn.telia.com. [213.67.202.254]) by smtp.googlemail.com with ESMTPSA id w7-20020a05651234c700b0049464d89e40sm902620lfr.72.2022.12.18.13.19.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Dec 2022 13:19:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=46C2MF6RZfVqrMZvxDPCl1p+Oawy3L4vspnUr+kuxSg=; b=SuHtJD+TqVsdi8cGt/UsgFD7BskAxt95Xc1JP31T0ZUe24Hs1g5dO0UpULtvB4Dser +xVoCTlz9Q5pyJ9i2wQfGkyKRu17u4AK6Ls2H7zvv60UHaEKhOQTaOnKHWvhHL62NpqT u+yV4agXTIsXnBmJARPqpFUjCGW/fZBQvuXqD9MD5UAnDbvAnRD0mYSpgSoah8c2iz4E fYJN7EwKCK+cTrtQnaTvx3wyZOLz87wQ/wcCZl0wC5SNs1RHVURYgrkRcfBwQVgwZUGI 7i2+4QdyTK7Z4CWfFlYz7McVl//NzENZuzr8ISaDwXKgYboBgi5I4LNka8poYcKtpwzm 6C5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=46C2MF6RZfVqrMZvxDPCl1p+Oawy3L4vspnUr+kuxSg=; b=oY/+NeRRAglP8d09OMHXoXzmie/W7aVmSbiljoBX0hfMXtDYZ5timk++B/SukQ2mcy n+ZBII0eNDrPQC6oGw7aS9ZjqHJvtIg9N1mR0eadhOhbiOzcSAl838Bo1hx6Y1vSBOCz oB4K5Zo0fNxGnzyG5TCnJbzBnOmM3mPz6AKfs3eov3Z+QUiBWmxq/NNR846l7NQlUEhB Ug7rISeFaDW04dbeSX1DYXhqWLWpofg80JCzCQHQUWCWW2NvA61yfVmBDSdLRguZ0TwZ mEPyFVyxwAtfiFUjzpF4IuAFmth8TgA8P9BMjMSCYwUlTY/hFXRF2vPviaYMUhTfhPQW 9LfA== X-Gm-Message-State: AFqh2koLmprPOKskRw4wv8+j1oJ5FSUHmsNy+HGIR9065tjqrOP8b0SS hSilUySsBUBP3Qd0mavb6SV8otpzBlcCMtgK X-Google-Smtp-Source: AMrXdXty4r1fFIDSE0WVSUIJascwDSayiUSZtMKc1Vq1A6lS6NwxcRxztb+Gf8z/46fbiyzwsw4UjQ== X-Received: by 2002:a05:6512:31d2:b0:4c2:fcbc:efa2 with SMTP id j18-20020a05651231d200b004c2fcbcefa2mr2954948lfe.44.1671398367522; Sun, 18 Dec 2022 13:19:27 -0800 (PST) From: Strahinja Jankovic X-Google-Original-From: Strahinja Jankovic To: Peter Maydell Cc: Beniamino Galvani , Niek Linnenbank , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Strahinja Jankovic Subject: [PATCH v2 7/7] docs/system/arm: Update Allwinner with TWI (I2C) Date: Sun, 18 Dec 2022 22:19:18 +0100 Message-Id: <20221218211918.3592-8-strahinja.p.jankovic@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> References: <20221218211918.3592-1-strahinja.p.jankovic@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::129; envelope-from=strahinjapjankovic@gmail.com; helo=mail-lf1-x129.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, WEIRD_QUOTING=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1671398479054100005 Content-Type: text/plain; charset="utf-8" TWI (I2C) is supported so docs are updated for Cubieboard and Orangepi-PC board. Signed-off-by: Strahinja Jankovic --- docs/system/arm/cubieboard.rst | 1 + docs/system/arm/orangepi.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst index 344ff8cef9..8d485f5435 100644 --- a/docs/system/arm/cubieboard.rst +++ b/docs/system/arm/cubieboard.rst @@ -14,3 +14,4 @@ Emulated devices: - SDHCI - USB controller - SATA controller +- TWI (I2C) controller diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst index 83c7445197..e5973600a1 100644 --- a/docs/system/arm/orangepi.rst +++ b/docs/system/arm/orangepi.rst @@ -25,6 +25,7 @@ The Orange Pi PC machine supports the following devices: * Clock Control Unit * System Control module * Security Identifier device + * TWI (I2C) =20 Limitations """"""""""" --=20 2.30.2