From patchwork Mon Jan 6 09:32:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 1218049 X-Patchwork-Delegate: monstr@monstr.eu Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.b="THJsrmKv"; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47rr032L6sz9sPJ for ; Mon, 6 Jan 2020 20:32:51 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 38C0B81708; Mon, 6 Jan 2020 10:32:42 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.b="THJsrmKv"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 271C781708; Mon, 6 Jan 2020 10:32:41 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8DDB080507 for ; Mon, 6 Jan 2020 10:32:38 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: phobos.denx.de; spf=none smtp.mailfrom=monstr@monstr.eu Received: by mail-wm1-x341.google.com with SMTP id t14so14553186wmi.5 for ; Mon, 06 Jan 2020 01:32:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monstr-eu.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XHS8nDb4NzQUcLKmCrO9/1fkICrhhOopcj4gZVmgaTI=; b=THJsrmKvETR0UF1P+jqRGgUtv9lhj8Dei9PfUwNT2ZvniPd82q3Sj6fMrxOYwEaWhb kH1OeJFNSkjBO42uIDHA1UOIOiXDmRu98n02I1JpVy/k/qsagBaWlbHW4FaUVaFzwXzS OX4DZ/9LSoFqf4V/5YCrmSTqaXkXtNCAOulCTeNcAbMJueartoQ1vZcqYNAlDB/qsRaC xBPtoGoE5VKrYiUZMhHRvf2dfaTq1pndnodkxmLco/HlMasePifhUZR5IguDNqew39W8 3aVTXI5z01xp2kslZncpxZQTzdvF1+yFd4VEYXJb8CAOmxNm7QHhW5PaCI+AoQBBEMd4 7ZSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=XHS8nDb4NzQUcLKmCrO9/1fkICrhhOopcj4gZVmgaTI=; b=KoW1mQYRl2vvNrvGEtpX/j7Cvu8/PEyhmtTXejFzopOXaKoVzcnsbPZ75lBhx4GnSV ArVYk2YogNLoMz/UVoi/3b36/GtnrF7FaeMYWAw8G/QT6CioqAwAA7suCdV3xYc58XjK TmgnYdHmV0CLNJ4S0Lf1KMHLjbU2hQbMVzUWSA8HPeSIuKuvybr0Ch0802uR3bk/+KXu RfdZm1fFtPQfM3ZsV0FOGblvRfZDWDZiGVL3EpaQI/xDFN4v+LQj9cUauoGxEKTLFs38 0ejZs0ZWeC/ZeAGQB5l3akX3IE/acjI7W2iPuChpyLNFxQKUsTXyFlN3ohKB0HSsmwFG R8Cg== X-Gm-Message-State: APjAAAWKDXYKkSpA2rfAkR+xOQOkNY4H7EPVJkXU+1SOIytZAzJ0eYMf QKl3cvstmETG6uCJiIrNFUe+vywh35NFOg== X-Google-Smtp-Source: APXvYqwXaACL7mbADF4PRpbcKtEseW0lQ2UqAn4YU4z2bvb7MK5FMy2E7oXtfp2JgBsjBdoCg1Rjag== X-Received: by 2002:a05:600c:2207:: with SMTP id z7mr32362436wml.138.1578303157915; Mon, 06 Jan 2020 01:32:37 -0800 (PST) Received: from localhost (nat-35.starnet.cz. [178.255.168.35]) by smtp.gmail.com with ESMTPSA id p7sm21869806wmp.31.2020.01.06.01.32.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 06 Jan 2020 01:32:37 -0800 (PST) From: Michal Simek To: u-boot@lists.denx.de, git@xilinx.com Subject: [PATCH 1/2] zynq: mtd: nand: Move zynq nand driver to driver model Date: Mon, 6 Jan 2020 10:32:32 +0100 Message-Id: <1f2b32fe465ab4934bc8117a3f2bf3e50d1b7584.1578303151.git.michal.simek@xilinx.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.26 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: T Karthik Reddy , Stefan Agner , Boris Brezillon , Miquel Raynal , Stefan Roese Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.101.4 at phobos.denx.de X-Virus-Status: Clean From: Ashok Reddy Soma Move the zynq nand driver to driver model. Select DM_MTD if zynq nand controller (NAND_ZYNQ) is selected. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek --- drivers/mtd/nand/raw/Kconfig | 1 + drivers/mtd/nand/raw/zynq_nand.c | 44 ++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index ec17653f4149..5de72fb46c02 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -281,6 +281,7 @@ endif config NAND_ZYNQ bool "Support for Zynq Nand controller" select SYS_NAND_SELF_INIT + select DM_MTD imply CMD_NAND help This enables Nand driver support for Nand flash controller diff --git a/drivers/mtd/nand/raw/zynq_nand.c b/drivers/mtd/nand/raw/zynq_nand.c index e932a58bf603..f322d1a81930 100644 --- a/drivers/mtd/nand/raw/zynq_nand.c +++ b/drivers/mtd/nand/raw/zynq_nand.c @@ -17,6 +17,7 @@ #include #include #include +#include /* The NAND flash driver defines */ #define ZYNQ_NAND_CMD_PHASE 1 @@ -124,18 +125,23 @@ struct zynq_nand_smc_regs { ZYNQ_SMC_BASEADDR) /* - * struct zynq_nand_info - Defines the NAND flash driver instance + * struct nand_config - Defines the NAND flash driver instance * @parts: Pointer to the mtd_partition structure * @nand_base: Virtual address of the NAND flash device * @end_cmd_pending: End command is pending * @end_cmd: End command */ -struct zynq_nand_info { +struct nand_config { void __iomem *nand_base; u8 end_cmd_pending; u8 end_cmd; }; +struct zynq_nand_info { + struct udevice *dev; + struct nand_chip nand_chip; +}; + /* * struct zynq_nand_command_format - Defines NAND flash command format * @start_cmd: First cycle command (Start command) @@ -782,7 +788,7 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command, struct nand_chip *chip = mtd->priv; const struct zynq_nand_command_format *curr_cmd = NULL; u8 addr_cycles = 0; - struct zynq_nand_info *xnand = (struct zynq_nand_info *)chip->priv; + struct nand_config *xnand = (struct nand_config *)chip->priv; void *cmd_addr; unsigned long cmd_data = 0; unsigned long cmd_phase_addr = 0; @@ -1046,9 +1052,11 @@ static int zynq_nand_check_is_16bit_bw_flash(void) return is_16bit_bw; } -static int zynq_nand_init(struct nand_chip *nand_chip, int devnum) +static int zynq_nand_probe(struct udevice *dev) { - struct zynq_nand_info *xnand; + struct zynq_nand_info *zynq = dev_get_priv(dev); + struct nand_chip *nand_chip = &zynq->nand_chip; + struct nand_config *xnand; struct mtd_info *mtd; unsigned long ecc_page_size; u8 maf_id, dev_id, i; @@ -1059,7 +1067,7 @@ static int zynq_nand_init(struct nand_chip *nand_chip, int devnum) int err = -1; int is_16bit_bw; - xnand = calloc(1, sizeof(struct zynq_nand_info)); + xnand = calloc(1, sizeof(struct nand_config)); if (!xnand) { printf("%s: failed to allocate\n", __func__); goto fail; @@ -1235,7 +1243,7 @@ static int zynq_nand_init(struct nand_chip *nand_chip, int devnum) printf("%s: nand_scan_tail failed\n", __func__); goto fail; } - if (nand_register(devnum, mtd)) + if (nand_register(0, mtd)) goto fail; return 0; fail: @@ -1243,12 +1251,26 @@ fail: return err; } -static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; +static const struct udevice_id zynq_nand_dt_ids[] = { + {.compatible = "arm,pl353-smc-r2p1",}, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(zynq_nand) = { + .name = "zynq-nand", + .id = UCLASS_MTD, + .of_match = zynq_nand_dt_ids, + .probe = zynq_nand_probe, + .priv_auto_alloc_size = sizeof(struct zynq_nand_info), +}; void board_nand_init(void) { - struct nand_chip *nand = &nand_chip[0]; + struct udevice *dev; + int ret; - if (zynq_nand_init(nand, 0)) - puts("ZYNQ NAND init failed\n"); + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_GET_DRIVER(zynq_nand), &dev); + if (ret && ret != -ENODEV) + pr_err("Failed to initialize %s. (error %d)\n", dev->name, ret); } From patchwork Mon Jan 6 09:32:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 1218050 X-Patchwork-Delegate: monstr@monstr.eu Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.b="cnmKO8OS"; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47rr0C4q3Tz9sPJ for ; Mon, 6 Jan 2020 20:32:59 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 6307B8170E; Mon, 6 Jan 2020 10:32:46 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.b="cnmKO8OS"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 429C181717; Mon, 6 Jan 2020 10:32:45 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 1FFEF80507 for ; Mon, 6 Jan 2020 10:32:42 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: phobos.denx.de; spf=none smtp.mailfrom=monstr@monstr.eu Received: by mail-wr1-x443.google.com with SMTP id t2so48855114wrr.1 for ; Mon, 06 Jan 2020 01:32:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monstr-eu.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/zVQAeiEygg+8ytLuvfZp++kFoTjP34wO9QV0EkeMZQ=; b=cnmKO8OSWjUFMJdR7NvJHLRvCK2iITFZVOvEtgW5vijGkIpGu9aVHPqq8o3Lyw6pLx e1SXNnprM8cr6yBmdiE4YhN/x3KfXbWbs1/kXCIUYrmsXDypvJwwlnEg7JfJkUu8sbJ4 gRa0JlyfCphs5y8Tk6mm/MmS9gzspmzmkp/+kCUZCRpvLnk5W6lzZkK+j0qESi9w6rlC PZye5kdpvfpn2g4w4m6Jprmz8AqGWuWWxtQ8AUMs0bn+7ChLOexLiqab7XO2Rn3jSX3w gE9H7ImGeQUcjftk4KPDUCjx5ISspJTagcGpMq39pC9oxfUIz82T4UVd04i2+slpOBEN aziQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=/zVQAeiEygg+8ytLuvfZp++kFoTjP34wO9QV0EkeMZQ=; b=BgkbRAYkaLn9P3r6oazinPRr5KBDe+0ci1IKRxsGbVyQi1Nh5y+WLmCTBgUhgxH4uD fdMuU5SpNBuj46XVPi0zCRfwncBKvALin5gz8aW8Ay10pk0cy4BWx9sq/dvf3qE0Gr1k xsmqaA9QZrZqwWFLWqGOILyD6uaKYBtel3YFknGIrAcnwlQCEm+I2OkBcvcsCl5FIyaL 8EIpAJsRr8O8fd3bbnQqa82m7QGlhgyh1qz8FRkIcC/vnNg4hPH3Ry61LkASWCf2Q9m2 UxZdVjINvT5LFTwDczCW/RkvGZDN5oFOybtR4iws3/i6rL87OqAJgkciMY0LMQD1oJHj hVyw== X-Gm-Message-State: APjAAAU0oVPRoTGHktL0pkZaXGGepxt3uhxG8oPKoBBX+895RwFmfLzG 8zd990jBnXB0j4PhrnLYbimRHI9wYuvG7A== X-Google-Smtp-Source: APXvYqxj2LYyzPZ9jflzLGpZBnLa0cLEMR3UiyC7gRJkS87NSIzhVouaxhu7Xsa7W6W/5xk0R5G45w== X-Received: by 2002:a5d:44cd:: with SMTP id z13mr102485391wrr.104.1578303161402; Mon, 06 Jan 2020 01:32:41 -0800 (PST) Received: from localhost (nat-35.starnet.cz. [178.255.168.35]) by smtp.gmail.com with ESMTPSA id e16sm70512850wrs.73.2020.01.06.01.32.39 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 06 Jan 2020 01:32:40 -0800 (PST) From: Michal Simek To: u-boot@lists.denx.de, git@xilinx.com Subject: [PATCH 2/2] zynq: mtd: nand: Remove hardcoded base addresses Date: Mon, 6 Jan 2020 10:32:33 +0100 Message-Id: X-Mailer: git-send-email 2.24.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.26 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.101.4 at phobos.denx.de X-Virus-Status: Clean From: Ashok Reddy Soma Remove hardcoded base addresses of smc controller and nand controller. Get those addresses from dt and replace wherever they are used. Remove smc and nand base address from header file too. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek --- arch/arm/mach-zynq/include/mach/hardware.h | 2 - drivers/mtd/nand/raw/zynq_nand.c | 94 +++++++++++++--------- 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/arch/arm/mach-zynq/include/mach/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h index 5412ed682797..0fe49aeb2276 100644 --- a/arch/arm/mach-zynq/include/mach/hardware.h +++ b/arch/arm/mach-zynq/include/mach/hardware.h @@ -10,8 +10,6 @@ #define ZYNQ_DEV_CFG_APB_BASEADDR 0xF8007000 #define ZYNQ_SCU_BASEADDR 0xF8F00000 #define ZYNQ_QSPI_BASEADDR 0xE000D000 -#define ZYNQ_SMC_BASEADDR 0xE000E000 -#define ZYNQ_NAND_BASEADDR 0xE1000000 #define ZYNQ_DDRC_BASEADDR 0xF8006000 #define ZYNQ_EFUSE_BASEADDR 0xF800D000 #define ZYNQ_USB_BASEADDR0 0xE0002000 diff --git a/drivers/mtd/nand/raw/zynq_nand.c b/drivers/mtd/nand/raw/zynq_nand.c index f322d1a81930..28db4153f5e0 100644 --- a/drivers/mtd/nand/raw/zynq_nand.c +++ b/drivers/mtd/nand/raw/zynq_nand.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -121,8 +122,6 @@ struct zynq_nand_smc_regs { u32 reserved2[2]; u32 eval0r; /* 0x418 */ }; -#define zynq_nand_smc_base ((struct zynq_nand_smc_regs __iomem *)\ - ZYNQ_SMC_BASEADDR) /* * struct nand_config - Defines the NAND flash driver instance @@ -137,8 +136,14 @@ struct nand_config { u8 end_cmd; }; +struct nand_drv { + struct zynq_nand_smc_regs *reg; + struct nand_config config; +}; + struct zynq_nand_info { struct udevice *dev; + struct nand_drv nand_ctrl; struct nand_chip nand_chip; }; @@ -245,16 +250,18 @@ static struct nand_bbt_descr bbt_mirror_descr = { * * returns: status for command completion, -1 for Timeout */ -static int zynq_nand_waitfor_ecc_completion(void) +static int zynq_nand_waitfor_ecc_completion(struct mtd_info *mtd) { + struct nand_chip *nand_chip = mtd_to_nand(mtd); + struct nand_drv *smc = nand_get_controller_data(nand_chip); unsigned long timeout; u32 status; /* Wait max 10us */ timeout = 10; - status = readl(&zynq_nand_smc_base->esr); + status = readl(&smc->reg->esr); while (status & ZYNQ_NAND_ECC_BUSY) { - status = readl(&zynq_nand_smc_base->esr); + status = readl(&smc->reg->esr); if (timeout == 0) return -1; timeout--; @@ -272,33 +279,35 @@ static int zynq_nand_waitfor_ecc_completion(void) * * returns: 0 on success or error value on failure */ -static int zynq_nand_init_nand_flash(int option) +static int zynq_nand_init_nand_flash(struct mtd_info *mtd, int option) { + struct nand_chip *nand_chip = mtd_to_nand(mtd); + struct nand_drv *smc = nand_get_controller_data(nand_chip); u32 status; /* disable interrupts */ - writel(ZYNQ_NAND_CLR_CONFIG, &zynq_nand_smc_base->cfr); + writel(ZYNQ_NAND_CLR_CONFIG, &smc->reg->cfr); #ifndef CONFIG_NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS /* Initialize the NAND interface by setting cycles and operation mode */ - writel(ZYNQ_NAND_SET_CYCLES, &zynq_nand_smc_base->scr); + writel(ZYNQ_NAND_SET_CYCLES, &smc->reg->scr); #endif if (option & NAND_BUSWIDTH_16) - writel(ZYNQ_NAND_SET_OPMODE_16BIT, &zynq_nand_smc_base->sor); + writel(ZYNQ_NAND_SET_OPMODE_16BIT, &smc->reg->sor); else - writel(ZYNQ_NAND_SET_OPMODE_8BIT, &zynq_nand_smc_base->sor); + writel(ZYNQ_NAND_SET_OPMODE_8BIT, &smc->reg->sor); - writel(ZYNQ_NAND_DIRECT_CMD, &zynq_nand_smc_base->dcr); + writel(ZYNQ_NAND_DIRECT_CMD, &smc->reg->dcr); /* Wait till the ECC operation is complete */ - status = zynq_nand_waitfor_ecc_completion(); + status = zynq_nand_waitfor_ecc_completion(mtd); if (status < 0) { printf("%s: Timeout\n", __func__); return status; } /* Set the command1 and command2 register */ - writel(ZYNQ_NAND_ECC_CMD1, &zynq_nand_smc_base->emcmd1r); - writel(ZYNQ_NAND_ECC_CMD2, &zynq_nand_smc_base->emcmd2r); + writel(ZYNQ_NAND_ECC_CMD1, &smc->reg->emcmd1r); + writel(ZYNQ_NAND_ECC_CMD2, &smc->reg->emcmd2r); return 0; } @@ -317,12 +326,14 @@ static int zynq_nand_init_nand_flash(int option) static int zynq_nand_calculate_hwecc(struct mtd_info *mtd, const u8 *data, u8 *ecc_code) { + struct nand_chip *nand_chip = mtd_to_nand(mtd); + struct nand_drv *smc = nand_get_controller_data(nand_chip); u32 ecc_value = 0; u8 ecc_reg, ecc_byte; u32 ecc_status; /* Wait till the ECC operation is complete */ - ecc_status = zynq_nand_waitfor_ecc_completion(); + ecc_status = zynq_nand_waitfor_ecc_completion(mtd); if (ecc_status < 0) { printf("%s: Timeout\n", __func__); return ecc_status; @@ -330,7 +341,7 @@ static int zynq_nand_calculate_hwecc(struct mtd_info *mtd, const u8 *data, for (ecc_reg = 0; ecc_reg < 4; ecc_reg++) { /* Read ECC value for each block */ - ecc_value = readl(&zynq_nand_smc_base->eval0r + ecc_reg); + ecc_value = readl(&smc->reg->eval0r + ecc_reg); /* Get the ecc status from ecc read value */ ecc_status = (ecc_value >> 24) & 0xFF; @@ -785,10 +796,11 @@ static void zynq_nand_select_chip(struct mtd_info *mtd, int chip) static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_drv *smc = nand_get_controller_data(chip); const struct zynq_nand_command_format *curr_cmd = NULL; u8 addr_cycles = 0; - struct nand_config *xnand = (struct nand_config *)chip->priv; + struct nand_config *xnand = &smc->config; void *cmd_addr; unsigned long cmd_data = 0; unsigned long cmd_phase_addr = 0; @@ -827,7 +839,7 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command, curr_cmd = &zynq_nand_commands[index]; /* Clear interrupt */ - writel(ZYNQ_MEMC_CLRCR_INT_CLR1, &zynq_nand_smc_base->cfr); + writel(ZYNQ_MEMC_CLRCR_INT_CLR1, &smc->reg->cfr); /* Get the command phase address */ if (curr_cmd->end_cmd_valid == ZYNQ_NAND_CMD_PHASE) @@ -924,7 +936,7 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command, */ static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); /* Make sure that buf is 32 bit aligned */ if (((unsigned long)buf & 0x3) != 0) { @@ -972,7 +984,7 @@ static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) */ static void zynq_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) { - struct nand_chip *chip = mtd->priv; + struct nand_chip *chip = mtd_to_nand(mtd); const u32 *nand = chip->IO_ADDR_W; /* Make sure that buf is 32 bit aligned */ @@ -1022,13 +1034,15 @@ static void zynq_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) */ static int zynq_nand_device_ready(struct mtd_info *mtd) { + struct nand_chip *nand_chip = mtd_to_nand(mtd); + struct nand_drv *smc = nand_get_controller_data(nand_chip); u32 csr_val; - csr_val = readl(&zynq_nand_smc_base->csr); + csr_val = readl(&smc->reg->csr); /* Check the raw_int_status1 bit */ if (csr_val & ZYNQ_MEMC_SR_RAW_INT_ST1) { /* Clear the interrupt condition */ - writel(ZYNQ_MEMC_SR_INT_ST1, &zynq_nand_smc_base->cfr); + writel(ZYNQ_MEMC_SR_INT_ST1, &smc->reg->cfr); return 1; } @@ -1056,8 +1070,11 @@ static int zynq_nand_probe(struct udevice *dev) { struct zynq_nand_info *zynq = dev_get_priv(dev); struct nand_chip *nand_chip = &zynq->nand_chip; - struct nand_config *xnand; + struct nand_drv *smc = &zynq->nand_ctrl; + struct nand_config *xnand = &smc->config; struct mtd_info *mtd; + struct resource res; + ofnode of_nand; unsigned long ecc_page_size; u8 maf_id, dev_id, i; u8 get_feature[4]; @@ -1067,17 +1084,20 @@ static int zynq_nand_probe(struct udevice *dev) int err = -1; int is_16bit_bw; - xnand = calloc(1, sizeof(struct nand_config)); - if (!xnand) { - printf("%s: failed to allocate\n", __func__); + smc->reg = (struct zynq_nand_smc_regs *)dev_read_addr(dev); + of_nand = dev_read_subnode(dev, "flash@e1000000"); + if (!ofnode_valid(of_nand)) { + printf("Failed to find nand node in dt\n"); + goto fail; + } + if (ofnode_read_resource(of_nand, 0, &res)) { + printf("Failed to get nand resource\n"); goto fail; } - xnand->nand_base = (void __iomem *)ZYNQ_NAND_BASEADDR; + xnand->nand_base = (void __iomem *)res.start; mtd = nand_to_mtd(nand_chip); - - nand_chip->priv = xnand; - mtd->priv = nand_chip; + nand_set_controller_data(nand_chip, &zynq->nand_ctrl); /* Set address of NAND IO lines */ nand_chip->IO_ADDR_R = xnand->nand_base; @@ -1108,7 +1128,7 @@ static int zynq_nand_probe(struct udevice *dev) nand_chip->bbt_options = NAND_BBT_USE_FLASH; /* Initialize the NAND flash interface on NAND controller */ - if (zynq_nand_init_nand_flash(nand_chip->options) < 0) { + if (zynq_nand_init_nand_flash(mtd, nand_chip->options) < 0) { printf("%s: nand flash init failed\n", __func__); goto fail; } @@ -1156,9 +1176,9 @@ static int zynq_nand_probe(struct udevice *dev) if (ondie_ecc_enabled) { /* Bypass the controller ECC block */ - ecc_cfg = readl(&zynq_nand_smc_base->emcr); + ecc_cfg = readl(&smc->reg->emcr); ecc_cfg &= ~ZYNQ_MEMC_NAND_ECC_MODE_MASK; - writel(ecc_cfg, &zynq_nand_smc_base->emcr); + writel(ecc_cfg, &smc->reg->emcr); /* The software ECC routines won't work * with the SMC controller @@ -1206,19 +1226,19 @@ static int zynq_nand_probe(struct udevice *dev) ecc_page_size = 0x1; /* Set the ECC memory config register */ writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size), - &zynq_nand_smc_base->emcr); + &smc->reg->emcr); break; case 1024: ecc_page_size = 0x2; /* Set the ECC memory config register */ writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size), - &zynq_nand_smc_base->emcr); + &smc->reg->emcr); break; case 2048: ecc_page_size = 0x3; /* Set the ECC memory config register */ writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size), - &zynq_nand_smc_base->emcr); + &smc->reg->emcr); break; default: nand_chip->ecc.mode = NAND_ECC_SOFT;