From patchwork Mon Jul 25 17:56:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Glauber X-Patchwork-Id: 9246269 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C05DD6077C for ; Mon, 25 Jul 2016 17:57:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5268252D2 for ; Mon, 25 Jul 2016 17:57:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A92BC2705B; Mon, 25 Jul 2016 17:57:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 051BF252D2 for ; Mon, 25 Jul 2016 17:57:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753442AbcGYR4r (ORCPT ); Mon, 25 Jul 2016 13:56:47 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:34723 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752923AbcGYR4p (ORCPT ); Mon, 25 Jul 2016 13:56:45 -0400 Received: by mail-wm0-f66.google.com with SMTP id q128so17787589wma.1; Mon, 25 Jul 2016 10:56:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hm7Jw2QaZTkHZfOvGvMgxSnlDa5NeJp8x5jVUwaOrlk=; b=ZBzokNM5qdyTG/I0mkhr2c0k35eUsrTy8a5UcQYuqZ7aRXehGiB1ukabf8QkI1F6jw EzEv3BXmKsYdg/9ippCEcsxkPSzoinY/k+xvlMemReS5TYBL7u+QHy465Tylou77p1Wb C0qItTBjJBc9xf2mly5UpPRMVh2IJi5KoGs7cM28gahgKvMo58UCG4mxGVKfJnVdmJ7O PT3aPh5R5cYJ0W9npi0eqOeZfyUrVISGZPKTP4foH6PkoWnqhrpWoBOW2O5gtGuxSWOX O++FHPMjulxtRfXn66QrjNZfmGuYbOjCkijuagABe25FkSedsf5za3GXquIAT8lDqUT/ zvxg== X-Gm-Message-State: ALyK8tI7Cktc3qvSawaph+21guIMRbp8RaLJTPVRR5uGutJRDC4j6XsPotB3hoYtJWwWFg== X-Received: by 10.28.175.16 with SMTP id y16mr31337543wme.64.1469469403873; Mon, 25 Jul 2016 10:56:43 -0700 (PDT) Received: from hardcore.fritz.box (HSI-KBW-109-193-046-058.hsi7.kabel-badenwuerttemberg.de. [109.193.46.58]) by smtp.gmail.com with ESMTPSA id a21sm28639878wma.10.2016.07.25.10.56.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 25 Jul 2016 10:56:43 -0700 (PDT) From: Jan Glauber To: Mark Brown Cc: linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, David Daney , "Steven J . Hill" , Jan Glauber Subject: [PATCH v2] spi: octeon: Add thunderx driver Date: Mon, 25 Jul 2016 19:56:22 +0200 Message-Id: <20160725175622.7167-1-jglauber@cavium.com> X-Mailer: git-send-email 2.9.0.rc0.21.g7777322 In-Reply-To: <57963ED3.4090402@caviumnetworks.com> References: <57963ED3.4090402@caviumnetworks.com> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add ThunderX SPI driver using the shared part from the Octeon driver. The main difference of the ThunderX driver is that it is a PCI device so probing is different. The system clock settings can be specified in device tree. Signed-off-by: Jan Glauber --- drivers/spi/Kconfig | 7 ++ drivers/spi/Makefile | 2 + drivers/spi/spi-cavium-thunderx.c | 140 ++++++++++++++++++++++++++++++++++++++ drivers/spi/spi-cavium.h | 3 + 4 files changed, 152 insertions(+) create mode 100644 drivers/spi/spi-cavium-thunderx.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4b931ec..e0ee112 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -630,6 +630,13 @@ config SPI_TEGRA20_SLINK help SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. +config SPI_THUNDERX + tristate "Cavium ThunderX SPI controller" + depends on (ARM64 || CONFIG_TEST) && 64BIT && PCI + help + SPI host driver for the hardware found on Cavium ThunderX + SOCs. + config SPI_TOPCLIFF_PCH tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI" depends on PCI && (X86_32 || MIPS || COMPILE_TEST) diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 185367e..133364b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -91,6 +91,8 @@ obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o obj-$(CONFIG_SPI_TEGRA20_SFLASH) += spi-tegra20-sflash.o obj-$(CONFIG_SPI_TEGRA20_SLINK) += spi-tegra20-slink.o obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o +spi-thunderx-objs := spi-cavium.o spi-cavium-thunderx.o +obj-$(CONFIG_SPI_THUNDERX) += spi-thunderx.o obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o obj-$(CONFIG_SPI_TXX9) += spi-txx9.o obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o diff --git a/drivers/spi/spi-cavium-thunderx.c b/drivers/spi/spi-cavium-thunderx.c new file mode 100644 index 0000000..28c3dcc --- /dev/null +++ b/drivers/spi/spi-cavium-thunderx.c @@ -0,0 +1,140 @@ +/* + * Cavium ThunderX SPI driver. + * + * Copyright (C) 2016 Cavium Inc. + * Authors: Jan Glauber + */ + +#include +#include +#include +#include +#include + +#include "spi-cavium.h" + +#define DRV_NAME "spi-thunderx" + +#define SYS_FREQ_DEFAULT 700000000 /* 700 Mhz */ + +static int thunderx_spi_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct device *dev = &pdev->dev; + struct spi_master *master; + struct octeon_spi *p; + int ret = -ENOENT; + + master = spi_alloc_master(dev, sizeof(struct octeon_spi)); + if (!master) + return -ENOMEM; + p = spi_master_get_devdata(master); + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(dev, "Failed to enable PCI device\n"); + goto out_free; + } + + ret = pci_request_regions(pdev, DRV_NAME); + if (ret) { + dev_err(dev, "PCI request regions failed 0x%x\n", ret); + goto out_disable; + } + + p->register_base = pci_ioremap_bar(pdev, 0); + if (!p->register_base) { + dev_err(dev, "Cannot map reg base\n"); + ret = -EINVAL; + goto out_region; + } + + p->regs.config = 0x1000; + p->regs.status = 0x1008; + p->regs.tx = 0x1010; + p->regs.data = 0x1080; + + p->clk = devm_clk_get(dev, NULL); + if (IS_ERR(p->clk)) + goto out_unmap; + + ret = clk_prepare_enable(p->clk); + if (ret) + goto out_clock_devm; + + p->sys_freq = clk_get_rate(p->clk); + if (!p->sys_freq) + p->sys_freq = SYS_FREQ_DEFAULT; + dev_info(dev, "Set system clock to %u\n", p->sys_freq); + + master->num_chipselect = 4; + master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | + SPI_LSB_FIRST | SPI_3WIRE; + master->transfer_one_message = octeon_spi_transfer_one_message; + master->bits_per_word_mask = SPI_BPW_MASK(8); + master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ; + master->dev.of_node = pdev->dev.of_node; + + pci_set_drvdata(pdev, master); + ret = devm_spi_register_master(dev, master); + if (ret) { + dev_err(&pdev->dev, "Register master failed: %d\n", ret); + goto out_clock; + } + + return 0; + +out_clock: + clk_disable_unprepare(p->clk); +out_clock_devm: + devm_clk_put(dev, p->clk); +out_unmap: + iounmap(p->register_base); +out_region: + pci_release_regions(pdev); +out_disable: + pci_disable_device(pdev); +out_free: + spi_master_put(master); + return ret; +} + +static void thunderx_spi_remove(struct pci_dev *pdev) +{ + struct spi_master *master = pci_get_drvdata(pdev); + struct octeon_spi *p; + + p = spi_master_get_devdata(master); + if (!p) + return; + + /* Put everything in a known state. */ + writeq(0, p->register_base + OCTEON_SPI_CFG(p)); + + clk_disable_unprepare(p->clk); + devm_clk_put(&pdev->dev, p->clk); + iounmap(p->register_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static const struct pci_device_id thunderx_spi_pci_id_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xa00b) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, thunderx_spi_pci_id_table); + +static struct pci_driver thunderx_spi_driver = { + .name = DRV_NAME, + .id_table = thunderx_spi_pci_id_table, + .probe = thunderx_spi_probe, + .remove = thunderx_spi_remove, +}; + +module_pci_driver(thunderx_spi_driver); + +MODULE_DESCRIPTION("Cavium, Inc. ThunderX SPI bus driver"); +MODULE_AUTHOR("Jan Glauber"); +MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi-cavium.h b/drivers/spi/spi-cavium.h index 88c5f36..1f91d61 100644 --- a/drivers/spi/spi-cavium.h +++ b/drivers/spi/spi-cavium.h @@ -1,6 +1,8 @@ #ifndef __SPI_CAVIUM_H #define __SPI_CAVIUM_H +#include + #define OCTEON_SPI_MAX_BYTES 9 #define OCTEON_SPI_MAX_CLOCK_HZ 16000000 @@ -17,6 +19,7 @@ struct octeon_spi { u64 cs_enax; int sys_freq; struct octeon_spi_regs regs; + struct clk *clk; }; #define OCTEON_SPI_CFG(x) (x->regs.config)