From patchwork Wed May 18 15:40:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sperl X-Patchwork-Id: 9120701 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C9A489F37F for ; Wed, 18 May 2016 15:42:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B10D420145 for ; Wed, 18 May 2016 15:42:43 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F38B20340 for ; Wed, 18 May 2016 15:42:41 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1b33b6-00039y-0s; Wed, 18 May 2016 15:41:20 +0000 Received: from 212-186-180-163.static.surfer.at ([212.186.180.163] helo=cgate.sperl.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1b33ap-00031v-BI; Wed, 18 May 2016 15:41:04 +0000 Received: from rasp3a.intern.sperl.org (account martin@sperl.org [10.10.10.43] verified) by sperl.org (CommuniGate Pro SMTP 6.1.2) with ESMTPSA id 6460085; Wed, 18 May 2016 15:40:35 +0000 From: kernel@martin.sperl.org To: Rob Herring , Pawel Moll , Mark Rutland , Stephen Warren , Lee Jones , Eric Anholt , Russell King , devicetree@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH-V2 2/6] memory: bcm2835: add bcm2835-memory controller Date: Wed, 18 May 2016 15:40:26 +0000 Message-Id: <1463586030-2778-3-git-send-email-kernel@martin.sperl.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1463586030-2778-1-git-send-email-kernel@martin.sperl.org> References: <1463586030-2778-1-git-send-email-kernel@martin.sperl.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160518_084103_883187_0F8DEE7F X-CRM114-Status: GOOD ( 17.76 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Martin Sperl MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Martin Sperl Add a memory-controller driver for the bcm2835 SOC. This is mostly needed to claim the SDRAM clocks so that this (and the corresponding parent pll) never gets disabled. Signed-off-by: Martin Sperl Changelog: V1->V2: moved to different register sets (that are also set up by the alternative boot loader to enable sdram) added 2 distinct clocks (for low voltage and internal pll) made the use of "names" for reg and clocks --- drivers/memory/Kconfig | 7 +++ drivers/memory/Makefile | 1 + drivers/memory/bcm2835-sdram.c | 128 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 drivers/memory/bcm2835-sdram.c diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 51d5cd2..a55cad3 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -25,6 +25,13 @@ config ATMEL_SDRAMC Starting with the at91sam9g45, this controller supports SDR, DDR and LP-DDR memories. +config BCM2835_SDRAM + bool "Broadcom BCM2835 SDRAM Controller" + default y + depends on ARCH_BCM2835 || COMPILE_TEST + help + This driver is for Broadcom BCM2835 SDRAM Controller. + config TI_AEMIF tristate "Texas Instruments AEMIF driver" depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index 890bdf4..1287b90 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_OF) += of_memory.o endif obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o +obj-$(CONFIG_BCM2835_SDRAM) += bcm2835-sdram.o obj-$(CONFIG_TI_AEMIF) += ti-aemif.o obj-$(CONFIG_TI_EMIF) += emif.o obj-$(CONFIG_OMAP_GPMC) += omap-gpmc.o diff --git a/drivers/memory/bcm2835-sdram.c b/drivers/memory/bcm2835-sdram.c new file mode 100644 index 0000000..ce985ee --- /dev/null +++ b/drivers/memory/bcm2835-sdram.c @@ -0,0 +1,128 @@ +/* + * Driver for Broadcom BCM2835 soc sdram controller + * + * Copyright (C) 2016 Martin Sperl + * + * inspired by: atmel-sdramc + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct bcm2835_sdram_data { + void __iomem *sdram_regs; + void __iomem *aphy_csr_regs; + void __iomem *dphy_csr_regs; + + struct clk *clk_lv; + struct clk *clk_pll_parent; +}; + +static int bcm2835_sdram_probe_reg(struct platform_device *pdev, + const char *name, + void __iomem **ptr) +{ + struct resource *res; + int err = 0; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + if (!res) { + dev_err(&pdev->dev, + "Could not find register range %s\n", + name); + return -EINVAL; + } + + *ptr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(*ptr)) { + err = PTR_ERR(*ptr); + dev_err(&pdev->dev, + "Could not get register range %s: %d\n", + name, err); + } + + return err; +} + +static int bcm2835_sdram_probe(struct platform_device *pdev) +{ + struct bcm2835_sdram_data *data; + int ret; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + platform_set_drvdata(pdev, data); + + /* get registers */ + ret = bcm2835_sdram_probe_reg(pdev, "sdram", + &data->sdram_regs); + if (ret) + return ret; + ret = bcm2835_sdram_probe_reg(pdev, "aphy_csr", + &data->aphy_csr_regs); + if (ret) + return ret; + ret = bcm2835_sdram_probe_reg(pdev, "dphy_csr", + &data->dphy_csr_regs); + if (ret) + return ret; + + /* get clocks */ + data->clk_lv = devm_clk_get(&pdev->dev, "low-voltage"); + if (IS_ERR(data->clk_lv)) { + ret = PTR_ERR(data->clk_lv); + dev_err(&pdev->dev, "Could not get clock named %s - %d\n", + "low-voltage", ret); + return ret; + } + data->clk_pll_parent = devm_clk_get(&pdev->dev, "pll-parent"); + if (IS_ERR(data->clk_pll_parent)) { + ret = PTR_ERR(data->clk_pll_parent); + dev_err(&pdev->dev, "Could not get clock named %s - %d\n", + "pll-parent", ret); + return ret; + } + + /* finally prepare both */ + clk_prepare_enable(data->clk_lv); + clk_prepare_enable(data->clk_pll_parent); + + return 0; +} + +static const struct of_device_id bcm2835_sdram_of_match_table[] = { + { .compatible = "brcm,bcm2835-sdram", }, + {}, +}; +MODULE_DEVICE_TABLE(of, bcm2835_sdram_of_match_table); + +static struct platform_driver bcm2835_sdram_driver = { + .probe = bcm2835_sdram_probe, + .driver = { + .name = "bcm2835_sdram", + .of_match_table = bcm2835_sdram_of_match_table, + }, +}; +module_platform_driver(bcm2835_sdram_driver); + +MODULE_AUTHOR("Martin Sperl"); +MODULE_DESCRIPTION("sdram driver for bcm2835 chip"); +MODULE_LICENSE("GPL");