From patchwork Fri Jan 13 06:23:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642556 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D6FDC71131 for ; Fri, 13 Jan 2023 06:25:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240371AbjAMGZJ (ORCPT ); Fri, 13 Jan 2023 01:25:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231345AbjAMGYV (ORCPT ); Fri, 13 Jan 2023 01:24:21 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDB1F5C1F3; Thu, 12 Jan 2023 22:23:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=ac+u1KmnA6x62YBZ9iTjcmD3FuUPV8lBO1ZPVqa0rj0=; b=nZ6HMmuRPN8kcNrlOz0w8CLN2m 2rSCbbadSwtWL6NoRw/ITTDGZypAgGb0FJRFALGG52nvTGYxofsmjPMxx9fYw7f/emo9nP3VgmMi1 5zLkaSMRb3QJEw23RkLS/GfvqhYREJSDZVHKhv3zU9QW5p/WH47sc8YOOcr203ghZzEs9bGTFUWo8 SAhUlBwNNV9ii/Q1UN3POf3qjtEYB/2dAqfZLh3xfThkEWRfgtfu6+h6+zN2Fj0wfSK6nTdRSY2qw DZsk9hVWPtXeYjzIzoYBLjew1mQzgC6PTRY/0xVpv8KpCy/SSOrPPqWGV+UCO816pBf9Op7faA1Gw wZmTeq9A==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDTc-000lMt-MQ; Fri, 13 Jan 2023 06:23:45 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 01/22] gpu/drm: remove the shmobile drm driver Date: Fri, 13 Jan 2023 07:23:18 +0100 Message-Id: <20230113062339.1909087-2-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org This driver depends on ARM && ARCH_SHMOBILE, but ARCH_SHMOBILE can only be set for each/sh, making the driver dead code except for the COMPILE_TEST case. Signed-off-by: Christoph Hellwig --- drivers/gpu/drm/Kconfig | 2 - drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/shmobile/Kconfig | 12 - drivers/gpu/drm/shmobile/Makefile | 8 - .../gpu/drm/shmobile/shmob_drm_backlight.c | 82 --- .../gpu/drm/shmobile/shmob_drm_backlight.h | 19 - drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 683 ------------------ drivers/gpu/drm/shmobile/shmob_drm_crtc.h | 55 -- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 303 -------- drivers/gpu/drm/shmobile/shmob_drm_drv.h | 42 -- drivers/gpu/drm/shmobile/shmob_drm_kms.c | 150 ---- drivers/gpu/drm/shmobile/shmob_drm_kms.h | 29 - drivers/gpu/drm/shmobile/shmob_drm_plane.c | 261 ------- drivers/gpu/drm/shmobile/shmob_drm_plane.h | 19 - drivers/gpu/drm/shmobile/shmob_drm_regs.h | 310 -------- 15 files changed, 1976 deletions(-) delete mode 100644 drivers/gpu/drm/shmobile/Kconfig delete mode 100644 drivers/gpu/drm/shmobile/Makefile delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_backlight.c delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_backlight.h delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_crtc.c delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_crtc.h delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_drv.c delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_drv.h delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_kms.c delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_kms.h delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_plane.c delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_plane.h delete mode 100644 drivers/gpu/drm/shmobile/shmob_drm_regs.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 315cbdf6197927..1cb4bcb0714c87 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -286,8 +286,6 @@ source "drivers/gpu/drm/atmel-hlcdc/Kconfig" source "drivers/gpu/drm/rcar-du/Kconfig" -source "drivers/gpu/drm/shmobile/Kconfig" - source "drivers/gpu/drm/sun4i/Kconfig" source "drivers/gpu/drm/omapdrm/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index cc637343d87b09..87709cf7db8145 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -160,7 +160,6 @@ obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_ARMADA) += armada/ obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/ obj-y += rcar-du/ -obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-y += omapdrm/ obj-$(CONFIG_DRM_SUN4I) += sun4i/ obj-y += tilcdc/ diff --git a/drivers/gpu/drm/shmobile/Kconfig b/drivers/gpu/drm/shmobile/Kconfig deleted file mode 100644 index 4ec5dc74a6b0b8..00000000000000 --- a/drivers/gpu/drm/shmobile/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config DRM_SHMOBILE - tristate "DRM Support for SH Mobile" - depends on DRM && ARM - depends on ARCH_SHMOBILE || COMPILE_TEST - select BACKLIGHT_CLASS_DEVICE - select DRM_KMS_HELPER - select DRM_GEM_DMA_HELPER - help - Choose this option if you have an SH Mobile chipset. - If M is selected the module will be called shmob-drm. - diff --git a/drivers/gpu/drm/shmobile/Makefile b/drivers/gpu/drm/shmobile/Makefile deleted file mode 100644 index 861edafed8562c..00000000000000 --- a/drivers/gpu/drm/shmobile/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -shmob-drm-y := shmob_drm_backlight.o \ - shmob_drm_crtc.o \ - shmob_drm_drv.o \ - shmob_drm_kms.o \ - shmob_drm_plane.o - -obj-$(CONFIG_DRM_SHMOBILE) += shmob-drm.o diff --git a/drivers/gpu/drm/shmobile/shmob_drm_backlight.c b/drivers/gpu/drm/shmobile/shmob_drm_backlight.c deleted file mode 100644 index 794573badfe860..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_backlight.c +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * shmob_drm_backlight.c -- SH Mobile DRM Backlight - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#include - -#include "shmob_drm_backlight.h" -#include "shmob_drm_crtc.h" -#include "shmob_drm_drv.h" - -static int shmob_drm_backlight_update(struct backlight_device *bdev) -{ - struct shmob_drm_connector *scon = bl_get_data(bdev); - struct shmob_drm_device *sdev = scon->connector.dev->dev_private; - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; - int brightness = backlight_get_brightness(bdev); - - return bdata->set_brightness(brightness); -} - -static int shmob_drm_backlight_get_brightness(struct backlight_device *bdev) -{ - struct shmob_drm_connector *scon = bl_get_data(bdev); - struct shmob_drm_device *sdev = scon->connector.dev->dev_private; - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; - - return bdata->get_brightness(); -} - -static const struct backlight_ops shmob_drm_backlight_ops = { - .options = BL_CORE_SUSPENDRESUME, - .update_status = shmob_drm_backlight_update, - .get_brightness = shmob_drm_backlight_get_brightness, -}; - -void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode) -{ - if (scon->backlight == NULL) - return; - - scon->backlight->props.power = mode == DRM_MODE_DPMS_ON - ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; - backlight_update_status(scon->backlight); -} - -int shmob_drm_backlight_init(struct shmob_drm_connector *scon) -{ - struct shmob_drm_device *sdev = scon->connector.dev->dev_private; - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; - struct drm_connector *connector = &scon->connector; - struct drm_device *dev = connector->dev; - struct backlight_device *backlight; - - if (!bdata->max_brightness) - return 0; - - backlight = backlight_device_register(bdata->name, dev->dev, scon, - &shmob_drm_backlight_ops, NULL); - if (IS_ERR(backlight)) { - dev_err(dev->dev, "unable to register backlight device: %ld\n", - PTR_ERR(backlight)); - return PTR_ERR(backlight); - } - - backlight->props.max_brightness = bdata->max_brightness; - backlight->props.brightness = bdata->max_brightness; - backlight->props.power = FB_BLANK_POWERDOWN; - backlight_update_status(backlight); - - scon->backlight = backlight; - return 0; -} - -void shmob_drm_backlight_exit(struct shmob_drm_connector *scon) -{ - backlight_device_unregister(scon->backlight); -} diff --git a/drivers/gpu/drm/shmobile/shmob_drm_backlight.h b/drivers/gpu/drm/shmobile/shmob_drm_backlight.h deleted file mode 100644 index d9abb7a60be5c4..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_backlight.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * shmob_drm_backlight.h -- SH Mobile DRM Backlight - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#ifndef __SHMOB_DRM_BACKLIGHT_H__ -#define __SHMOB_DRM_BACKLIGHT_H__ - -struct shmob_drm_connector; - -void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode); -int shmob_drm_backlight_init(struct shmob_drm_connector *scon); -void shmob_drm_backlight_exit(struct shmob_drm_connector *scon); - -#endif /* __SHMOB_DRM_BACKLIGHT_H__ */ diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c deleted file mode 100644 index 4624c0aff51ffa..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +++ /dev/null @@ -1,683 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * shmob_drm_crtc.c -- SH Mobile DRM CRTCs - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "shmob_drm_backlight.h" -#include "shmob_drm_crtc.h" -#include "shmob_drm_drv.h" -#include "shmob_drm_kms.h" -#include "shmob_drm_plane.h" -#include "shmob_drm_regs.h" - -/* - * TODO: panel support - */ - -/* ----------------------------------------------------------------------------- - * Clock management - */ - -static int shmob_drm_clk_on(struct shmob_drm_device *sdev) -{ - int ret; - - if (sdev->clock) { - ret = clk_prepare_enable(sdev->clock); - if (ret < 0) - return ret; - } - - return 0; -} - -static void shmob_drm_clk_off(struct shmob_drm_device *sdev) -{ - if (sdev->clock) - clk_disable_unprepare(sdev->clock); -} - -/* ----------------------------------------------------------------------------- - * CRTC - */ - -static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc) -{ - struct drm_crtc *crtc = &scrtc->crtc; - struct shmob_drm_device *sdev = crtc->dev->dev_private; - const struct shmob_drm_interface_data *idata = &sdev->pdata->iface; - const struct drm_display_mode *mode = &crtc->mode; - u32 value; - - value = sdev->ldmt1r - | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL) - | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL) - | ((idata->flags & SHMOB_DRM_IFACE_FL_DWPOL) ? LDMT1R_DWPOL : 0) - | ((idata->flags & SHMOB_DRM_IFACE_FL_DIPOL) ? LDMT1R_DIPOL : 0) - | ((idata->flags & SHMOB_DRM_IFACE_FL_DAPOL) ? LDMT1R_DAPOL : 0) - | ((idata->flags & SHMOB_DRM_IFACE_FL_HSCNT) ? LDMT1R_HSCNT : 0) - | ((idata->flags & SHMOB_DRM_IFACE_FL_DWCNT) ? LDMT1R_DWCNT : 0); - lcdc_write(sdev, LDMT1R, value); - - if (idata->interface >= SHMOB_DRM_IFACE_SYS8A && - idata->interface <= SHMOB_DRM_IFACE_SYS24) { - /* Setup SYS bus. */ - value = (idata->sys.cs_setup << LDMT2R_CSUP_SHIFT) - | (idata->sys.vsync_active_high ? LDMT2R_RSV : 0) - | (idata->sys.vsync_dir_input ? LDMT2R_VSEL : 0) - | (idata->sys.write_setup << LDMT2R_WCSC_SHIFT) - | (idata->sys.write_cycle << LDMT2R_WCEC_SHIFT) - | (idata->sys.write_strobe << LDMT2R_WCLW_SHIFT); - lcdc_write(sdev, LDMT2R, value); - - value = (idata->sys.read_latch << LDMT3R_RDLC_SHIFT) - | (idata->sys.read_setup << LDMT3R_RCSC_SHIFT) - | (idata->sys.read_cycle << LDMT3R_RCEC_SHIFT) - | (idata->sys.read_strobe << LDMT3R_RCLW_SHIFT); - lcdc_write(sdev, LDMT3R, value); - } - - value = ((mode->hdisplay / 8) << 16) /* HDCN */ - | (mode->htotal / 8); /* HTCN */ - lcdc_write(sdev, LDHCNR, value); - - value = (((mode->hsync_end - mode->hsync_start) / 8) << 16) /* HSYNW */ - | (mode->hsync_start / 8); /* HSYNP */ - lcdc_write(sdev, LDHSYNR, value); - - value = ((mode->hdisplay & 7) << 24) | ((mode->htotal & 7) << 16) - | (((mode->hsync_end - mode->hsync_start) & 7) << 8) - | (mode->hsync_start & 7); - lcdc_write(sdev, LDHAJR, value); - - value = ((mode->vdisplay) << 16) /* VDLN */ - | mode->vtotal; /* VTLN */ - lcdc_write(sdev, LDVLNR, value); - - value = ((mode->vsync_end - mode->vsync_start) << 16) /* VSYNW */ - | mode->vsync_start; /* VSYNP */ - lcdc_write(sdev, LDVSYNR, value); -} - -static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start) -{ - struct shmob_drm_device *sdev = scrtc->crtc.dev->dev_private; - u32 value; - - value = lcdc_read(sdev, LDCNT2R); - if (start) - lcdc_write(sdev, LDCNT2R, value | LDCNT2R_DO); - else - lcdc_write(sdev, LDCNT2R, value & ~LDCNT2R_DO); - - /* Wait until power is applied/stopped. */ - while (1) { - value = lcdc_read(sdev, LDPMR) & LDPMR_LPS; - if ((start && value) || (!start && !value)) - break; - - cpu_relax(); - } - - if (!start) { - /* Stop the dot clock. */ - lcdc_write(sdev, LDDCKSTPR, LDDCKSTPR_DCKSTP); - } -} - -/* - * shmob_drm_crtc_start - Configure and start the LCDC - * @scrtc: the SH Mobile CRTC - * - * Configure and start the LCDC device. External devices (clocks, MERAM, panels, - * ...) are not touched by this function. - */ -static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc) -{ - struct drm_crtc *crtc = &scrtc->crtc; - struct shmob_drm_device *sdev = crtc->dev->dev_private; - const struct shmob_drm_interface_data *idata = &sdev->pdata->iface; - const struct shmob_drm_format_info *format; - struct drm_device *dev = sdev->ddev; - struct drm_plane *plane; - u32 value; - int ret; - - if (scrtc->started) - return; - - format = shmob_drm_format_info(crtc->primary->fb->format->format); - if (WARN_ON(format == NULL)) - return; - - /* Enable clocks before accessing the hardware. */ - ret = shmob_drm_clk_on(sdev); - if (ret < 0) - return; - - /* Reset and enable the LCDC. */ - lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR); - lcdc_wait_bit(sdev, LDCNT2R, LDCNT2R_BR, 0); - lcdc_write(sdev, LDCNT2R, LDCNT2R_ME); - - /* Stop the LCDC first and disable all interrupts. */ - shmob_drm_crtc_start_stop(scrtc, false); - lcdc_write(sdev, LDINTR, 0); - - /* Configure power supply, dot clocks and start them. */ - lcdc_write(sdev, LDPMR, 0); - - value = sdev->lddckr; - if (idata->clk_div) { - /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider - * denominator. - */ - lcdc_write(sdev, LDDCKPAT1R, 0); - lcdc_write(sdev, LDDCKPAT2R, (1 << (idata->clk_div / 2)) - 1); - - if (idata->clk_div == 1) - value |= LDDCKR_MOSEL; - else - value |= idata->clk_div; - } - - lcdc_write(sdev, LDDCKR, value); - lcdc_write(sdev, LDDCKSTPR, 0); - lcdc_wait_bit(sdev, LDDCKSTPR, ~0, 0); - - /* TODO: Setup SYS panel */ - - /* Setup geometry, format, frame buffer memory and operation mode. */ - shmob_drm_crtc_setup_geometry(scrtc); - - /* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */ - lcdc_write(sdev, LDDFR, format->lddfr | LDDFR_CF1); - lcdc_write(sdev, LDMLSR, scrtc->line_size); - lcdc_write(sdev, LDSA1R, scrtc->dma[0]); - if (format->yuv) - lcdc_write(sdev, LDSA2R, scrtc->dma[1]); - lcdc_write(sdev, LDSM1R, 0); - - /* Word and long word swap. */ - switch (format->fourcc) { - case DRM_FORMAT_RGB565: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV61: - case DRM_FORMAT_NV42: - value = LDDDSR_LS | LDDDSR_WS; - break; - case DRM_FORMAT_RGB888: - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV24: - value = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS; - break; - case DRM_FORMAT_ARGB8888: - default: - value = LDDDSR_LS; - break; - } - lcdc_write(sdev, LDDDSR, value); - - /* Setup planes. */ - drm_for_each_legacy_plane(plane, dev) { - if (plane->crtc == crtc) - shmob_drm_plane_setup(plane); - } - - /* Enable the display output. */ - lcdc_write(sdev, LDCNT1R, LDCNT1R_DE); - - shmob_drm_crtc_start_stop(scrtc, true); - - scrtc->started = true; -} - -static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc) -{ - struct drm_crtc *crtc = &scrtc->crtc; - struct shmob_drm_device *sdev = crtc->dev->dev_private; - - if (!scrtc->started) - return; - - /* Stop the LCDC. */ - shmob_drm_crtc_start_stop(scrtc, false); - - /* Disable the display output. */ - lcdc_write(sdev, LDCNT1R, 0); - - /* Stop clocks. */ - shmob_drm_clk_off(sdev); - - scrtc->started = false; -} - -void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc) -{ - shmob_drm_crtc_stop(scrtc); -} - -void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc) -{ - if (scrtc->dpms != DRM_MODE_DPMS_ON) - return; - - shmob_drm_crtc_start(scrtc); -} - -static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc, - int x, int y) -{ - struct drm_crtc *crtc = &scrtc->crtc; - struct drm_framebuffer *fb = crtc->primary->fb; - struct drm_gem_dma_object *gem; - unsigned int bpp; - - bpp = scrtc->format->yuv ? 8 : scrtc->format->bpp; - gem = drm_fb_dma_get_gem_obj(fb, 0); - scrtc->dma[0] = gem->dma_addr + fb->offsets[0] - + y * fb->pitches[0] + x * bpp / 8; - - if (scrtc->format->yuv) { - bpp = scrtc->format->bpp - 8; - gem = drm_fb_dma_get_gem_obj(fb, 1); - scrtc->dma[1] = gem->dma_addr + fb->offsets[1] - + y / (bpp == 4 ? 2 : 1) * fb->pitches[1] - + x * (bpp == 16 ? 2 : 1); - } -} - -static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc) -{ - struct drm_crtc *crtc = &scrtc->crtc; - struct shmob_drm_device *sdev = crtc->dev->dev_private; - - shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y); - - lcdc_write_mirror(sdev, LDSA1R, scrtc->dma[0]); - if (scrtc->format->yuv) - lcdc_write_mirror(sdev, LDSA2R, scrtc->dma[1]); - - lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS); -} - -#define to_shmob_crtc(c) container_of(c, struct shmob_drm_crtc, crtc) - -static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); - - if (scrtc->dpms == mode) - return; - - if (mode == DRM_MODE_DPMS_ON) - shmob_drm_crtc_start(scrtc); - else - shmob_drm_crtc_stop(scrtc); - - scrtc->dpms = mode; -} - -static void shmob_drm_crtc_mode_prepare(struct drm_crtc *crtc) -{ - shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); - struct shmob_drm_device *sdev = crtc->dev->dev_private; - const struct shmob_drm_format_info *format; - - format = shmob_drm_format_info(crtc->primary->fb->format->format); - if (format == NULL) { - dev_dbg(sdev->dev, "mode_set: unsupported format %08x\n", - crtc->primary->fb->format->format); - return -EINVAL; - } - - scrtc->format = format; - scrtc->line_size = crtc->primary->fb->pitches[0]; - - shmob_drm_crtc_compute_base(scrtc, x, y); - - return 0; -} - -static void shmob_drm_crtc_mode_commit(struct drm_crtc *crtc) -{ - shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON); -} - -static int shmob_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - shmob_drm_crtc_update_base(to_shmob_crtc(crtc)); - - return 0; -} - -static const struct drm_crtc_helper_funcs crtc_helper_funcs = { - .dpms = shmob_drm_crtc_dpms, - .prepare = shmob_drm_crtc_mode_prepare, - .commit = shmob_drm_crtc_mode_commit, - .mode_set = shmob_drm_crtc_mode_set, - .mode_set_base = shmob_drm_crtc_mode_set_base, -}; - -void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc) -{ - struct drm_pending_vblank_event *event; - struct drm_device *dev = scrtc->crtc.dev; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - event = scrtc->event; - scrtc->event = NULL; - if (event) { - drm_crtc_send_vblank_event(&scrtc->crtc, event); - drm_crtc_vblank_put(&scrtc->crtc); - } - spin_unlock_irqrestore(&dev->event_lock, flags); -} - -static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags, - struct drm_modeset_acquire_ctx *ctx) -{ - struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); - struct drm_device *dev = scrtc->crtc.dev; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - if (scrtc->event != NULL) { - spin_unlock_irqrestore(&dev->event_lock, flags); - return -EBUSY; - } - spin_unlock_irqrestore(&dev->event_lock, flags); - - crtc->primary->fb = fb; - shmob_drm_crtc_update_base(scrtc); - - if (event) { - event->pipe = 0; - drm_crtc_vblank_get(&scrtc->crtc); - spin_lock_irqsave(&dev->event_lock, flags); - scrtc->event = event; - spin_unlock_irqrestore(&dev->event_lock, flags); - } - - return 0; -} - -static void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev, - bool enable) -{ - unsigned long flags; - u32 ldintr; - - /* Be careful not to acknowledge any pending interrupt. */ - spin_lock_irqsave(&sdev->irq_lock, flags); - ldintr = lcdc_read(sdev, LDINTR) | LDINTR_STATUS_MASK; - if (enable) - ldintr |= LDINTR_VEE; - else - ldintr &= ~LDINTR_VEE; - lcdc_write(sdev, LDINTR, ldintr); - spin_unlock_irqrestore(&sdev->irq_lock, flags); -} - -static int shmob_drm_enable_vblank(struct drm_crtc *crtc) -{ - struct shmob_drm_device *sdev = crtc->dev->dev_private; - - shmob_drm_crtc_enable_vblank(sdev, true); - - return 0; -} - -static void shmob_drm_disable_vblank(struct drm_crtc *crtc) -{ - struct shmob_drm_device *sdev = crtc->dev->dev_private; - - shmob_drm_crtc_enable_vblank(sdev, false); -} - -static const struct drm_crtc_funcs crtc_funcs = { - .destroy = drm_crtc_cleanup, - .set_config = drm_crtc_helper_set_config, - .page_flip = shmob_drm_crtc_page_flip, - .enable_vblank = shmob_drm_enable_vblank, - .disable_vblank = shmob_drm_disable_vblank, -}; - -int shmob_drm_crtc_create(struct shmob_drm_device *sdev) -{ - struct drm_crtc *crtc = &sdev->crtc.crtc; - int ret; - - sdev->crtc.dpms = DRM_MODE_DPMS_OFF; - - ret = drm_crtc_init(sdev->ddev, crtc, &crtc_funcs); - if (ret < 0) - return ret; - - drm_crtc_helper_add(crtc, &crtc_helper_funcs); - - return 0; -} - -/* ----------------------------------------------------------------------------- - * Encoder - */ - -#define to_shmob_encoder(e) \ - container_of(e, struct shmob_drm_encoder, encoder) - -static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct shmob_drm_encoder *senc = to_shmob_encoder(encoder); - struct shmob_drm_device *sdev = encoder->dev->dev_private; - struct shmob_drm_connector *scon = &sdev->connector; - - if (senc->dpms == mode) - return; - - shmob_drm_backlight_dpms(scon, mode); - - senc->dpms = mode; -} - -static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct shmob_drm_device *sdev = dev->dev_private; - struct drm_connector *connector = &sdev->connector.connector; - const struct drm_display_mode *panel_mode; - - if (list_empty(&connector->modes)) { - dev_dbg(dev->dev, "mode_fixup: empty modes list\n"); - return false; - } - - /* The flat panel mode is fixed, just copy it to the adjusted mode. */ - panel_mode = list_first_entry(&connector->modes, - struct drm_display_mode, head); - drm_mode_copy(adjusted_mode, panel_mode); - - return true; -} - -static void shmob_drm_encoder_mode_prepare(struct drm_encoder *encoder) -{ - /* No-op, everything is handled in the CRTC code. */ -} - -static void shmob_drm_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* No-op, everything is handled in the CRTC code. */ -} - -static void shmob_drm_encoder_mode_commit(struct drm_encoder *encoder) -{ - /* No-op, everything is handled in the CRTC code. */ -} - -static const struct drm_encoder_helper_funcs encoder_helper_funcs = { - .dpms = shmob_drm_encoder_dpms, - .mode_fixup = shmob_drm_encoder_mode_fixup, - .prepare = shmob_drm_encoder_mode_prepare, - .commit = shmob_drm_encoder_mode_commit, - .mode_set = shmob_drm_encoder_mode_set, -}; - -int shmob_drm_encoder_create(struct shmob_drm_device *sdev) -{ - struct drm_encoder *encoder = &sdev->encoder.encoder; - int ret; - - sdev->encoder.dpms = DRM_MODE_DPMS_OFF; - - encoder->possible_crtcs = 1; - - ret = drm_simple_encoder_init(sdev->ddev, encoder, - DRM_MODE_ENCODER_LVDS); - if (ret < 0) - return ret; - - drm_encoder_helper_add(encoder, &encoder_helper_funcs); - - return 0; -} - -/* ----------------------------------------------------------------------------- - * Connector - */ - -#define to_shmob_connector(c) \ - container_of(c, struct shmob_drm_connector, connector) - -static int shmob_drm_connector_get_modes(struct drm_connector *connector) -{ - struct shmob_drm_device *sdev = connector->dev->dev_private; - struct drm_display_mode *mode; - - mode = drm_mode_create(connector->dev); - if (mode == NULL) - return 0; - - mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; - mode->clock = sdev->pdata->panel.mode.clock; - mode->hdisplay = sdev->pdata->panel.mode.hdisplay; - mode->hsync_start = sdev->pdata->panel.mode.hsync_start; - mode->hsync_end = sdev->pdata->panel.mode.hsync_end; - mode->htotal = sdev->pdata->panel.mode.htotal; - mode->vdisplay = sdev->pdata->panel.mode.vdisplay; - mode->vsync_start = sdev->pdata->panel.mode.vsync_start; - mode->vsync_end = sdev->pdata->panel.mode.vsync_end; - mode->vtotal = sdev->pdata->panel.mode.vtotal; - mode->flags = sdev->pdata->panel.mode.flags; - - drm_mode_set_name(mode); - drm_mode_probed_add(connector, mode); - - connector->display_info.width_mm = sdev->pdata->panel.width_mm; - connector->display_info.height_mm = sdev->pdata->panel.height_mm; - - return 1; -} - -static struct drm_encoder * -shmob_drm_connector_best_encoder(struct drm_connector *connector) -{ - struct shmob_drm_connector *scon = to_shmob_connector(connector); - - return scon->encoder; -} - -static const struct drm_connector_helper_funcs connector_helper_funcs = { - .get_modes = shmob_drm_connector_get_modes, - .best_encoder = shmob_drm_connector_best_encoder, -}; - -static void shmob_drm_connector_destroy(struct drm_connector *connector) -{ - struct shmob_drm_connector *scon = to_shmob_connector(connector); - - shmob_drm_backlight_exit(scon); - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -} - -static const struct drm_connector_funcs connector_funcs = { - .dpms = drm_helper_connector_dpms, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = shmob_drm_connector_destroy, -}; - -int shmob_drm_connector_create(struct shmob_drm_device *sdev, - struct drm_encoder *encoder) -{ - struct drm_connector *connector = &sdev->connector.connector; - int ret; - - sdev->connector.encoder = encoder; - - connector->display_info.width_mm = sdev->pdata->panel.width_mm; - connector->display_info.height_mm = sdev->pdata->panel.height_mm; - - ret = drm_connector_init(sdev->ddev, connector, &connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - if (ret < 0) - return ret; - - drm_connector_helper_add(connector, &connector_helper_funcs); - - ret = shmob_drm_backlight_init(&sdev->connector); - if (ret < 0) - goto err_cleanup; - - ret = drm_connector_attach_encoder(connector, encoder); - if (ret < 0) - goto err_backlight; - - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - drm_object_property_set_value(&connector->base, - sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); - - return 0; - -err_backlight: - shmob_drm_backlight_exit(&sdev->connector); -err_cleanup: - drm_connector_cleanup(connector); - return ret; -} diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/shmobile/shmob_drm_crtc.h deleted file mode 100644 index 21718843f46d3d..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * shmob_drm_crtc.h -- SH Mobile DRM CRTCs - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#ifndef __SHMOB_DRM_CRTC_H__ -#define __SHMOB_DRM_CRTC_H__ - -#include -#include -#include - -struct backlight_device; -struct drm_pending_vblank_event; -struct shmob_drm_device; -struct shmob_drm_format_info; - -struct shmob_drm_crtc { - struct drm_crtc crtc; - - struct drm_pending_vblank_event *event; - int dpms; - - const struct shmob_drm_format_info *format; - unsigned long dma[2]; - unsigned int line_size; - bool started; -}; - -struct shmob_drm_encoder { - struct drm_encoder encoder; - int dpms; -}; - -struct shmob_drm_connector { - struct drm_connector connector; - struct drm_encoder *encoder; - - struct backlight_device *backlight; -}; - -int shmob_drm_crtc_create(struct shmob_drm_device *sdev); -void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc); -void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc); -void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc); - -int shmob_drm_encoder_create(struct shmob_drm_device *sdev); -int shmob_drm_connector_create(struct shmob_drm_device *sdev, - struct drm_encoder *encoder); - -#endif /* __SHMOB_DRM_CRTC_H__ */ diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c deleted file mode 100644 index 3d511fa3891364..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ /dev/null @@ -1,303 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * shmob_drm_drv.c -- SH Mobile DRM driver - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "shmob_drm_drv.h" -#include "shmob_drm_kms.h" -#include "shmob_drm_plane.h" -#include "shmob_drm_regs.h" - -/* ----------------------------------------------------------------------------- - * Hardware initialization - */ - -static int shmob_drm_init_interface(struct shmob_drm_device *sdev) -{ - static const u32 ldmt1r[] = { - [SHMOB_DRM_IFACE_RGB8] = LDMT1R_MIFTYP_RGB8, - [SHMOB_DRM_IFACE_RGB9] = LDMT1R_MIFTYP_RGB9, - [SHMOB_DRM_IFACE_RGB12A] = LDMT1R_MIFTYP_RGB12A, - [SHMOB_DRM_IFACE_RGB12B] = LDMT1R_MIFTYP_RGB12B, - [SHMOB_DRM_IFACE_RGB16] = LDMT1R_MIFTYP_RGB16, - [SHMOB_DRM_IFACE_RGB18] = LDMT1R_MIFTYP_RGB18, - [SHMOB_DRM_IFACE_RGB24] = LDMT1R_MIFTYP_RGB24, - [SHMOB_DRM_IFACE_YUV422] = LDMT1R_MIFTYP_YCBCR, - [SHMOB_DRM_IFACE_SYS8A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8A, - [SHMOB_DRM_IFACE_SYS8B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8B, - [SHMOB_DRM_IFACE_SYS8C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8C, - [SHMOB_DRM_IFACE_SYS8D] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8D, - [SHMOB_DRM_IFACE_SYS9] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS9, - [SHMOB_DRM_IFACE_SYS12] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS12, - [SHMOB_DRM_IFACE_SYS16A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16A, - [SHMOB_DRM_IFACE_SYS16B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16B, - [SHMOB_DRM_IFACE_SYS16C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16C, - [SHMOB_DRM_IFACE_SYS18] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS18, - [SHMOB_DRM_IFACE_SYS24] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS24, - }; - - if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) { - dev_err(sdev->dev, "invalid interface type %u\n", - sdev->pdata->iface.interface); - return -EINVAL; - } - - sdev->ldmt1r = ldmt1r[sdev->pdata->iface.interface]; - return 0; -} - -static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev, - enum shmob_drm_clk_source clksrc) -{ - struct clk *clk; - char *clkname; - - switch (clksrc) { - case SHMOB_DRM_CLK_BUS: - clkname = "bus_clk"; - sdev->lddckr = LDDCKR_ICKSEL_BUS; - break; - case SHMOB_DRM_CLK_PERIPHERAL: - clkname = "peripheral_clk"; - sdev->lddckr = LDDCKR_ICKSEL_MIPI; - break; - case SHMOB_DRM_CLK_EXTERNAL: - clkname = NULL; - sdev->lddckr = LDDCKR_ICKSEL_HDMI; - break; - default: - return -EINVAL; - } - - clk = devm_clk_get(sdev->dev, clkname); - if (IS_ERR(clk)) { - dev_err(sdev->dev, "cannot get dot clock %s\n", clkname); - return PTR_ERR(clk); - } - - sdev->clock = clk; - return 0; -} - -/* ----------------------------------------------------------------------------- - * DRM operations - */ - -static irqreturn_t shmob_drm_irq(int irq, void *arg) -{ - struct drm_device *dev = arg; - struct shmob_drm_device *sdev = dev->dev_private; - unsigned long flags; - u32 status; - - /* Acknowledge interrupts. Putting interrupt enable and interrupt flag - * bits in the same register is really brain-dead design and requires - * taking a spinlock. - */ - spin_lock_irqsave(&sdev->irq_lock, flags); - status = lcdc_read(sdev, LDINTR); - lcdc_write(sdev, LDINTR, status ^ LDINTR_STATUS_MASK); - spin_unlock_irqrestore(&sdev->irq_lock, flags); - - if (status & LDINTR_VES) { - drm_handle_vblank(dev, 0); - shmob_drm_crtc_finish_page_flip(&sdev->crtc); - } - - return IRQ_HANDLED; -} - -DEFINE_DRM_GEM_DMA_FOPS(shmob_drm_fops); - -static const struct drm_driver shmob_drm_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET, - DRM_GEM_DMA_DRIVER_OPS, - .fops = &shmob_drm_fops, - .name = "shmob-drm", - .desc = "Renesas SH Mobile DRM", - .date = "20120424", - .major = 1, - .minor = 0, -}; - -/* ----------------------------------------------------------------------------- - * Power management - */ - -#ifdef CONFIG_PM_SLEEP -static int shmob_drm_pm_suspend(struct device *dev) -{ - struct shmob_drm_device *sdev = dev_get_drvdata(dev); - - drm_kms_helper_poll_disable(sdev->ddev); - shmob_drm_crtc_suspend(&sdev->crtc); - - return 0; -} - -static int shmob_drm_pm_resume(struct device *dev) -{ - struct shmob_drm_device *sdev = dev_get_drvdata(dev); - - drm_modeset_lock_all(sdev->ddev); - shmob_drm_crtc_resume(&sdev->crtc); - drm_modeset_unlock_all(sdev->ddev); - - drm_kms_helper_poll_enable(sdev->ddev); - return 0; -} -#endif - -static const struct dev_pm_ops shmob_drm_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(shmob_drm_pm_suspend, shmob_drm_pm_resume) -}; - -/* ----------------------------------------------------------------------------- - * Platform driver - */ - -static int shmob_drm_remove(struct platform_device *pdev) -{ - struct shmob_drm_device *sdev = platform_get_drvdata(pdev); - struct drm_device *ddev = sdev->ddev; - - drm_dev_unregister(ddev); - drm_kms_helper_poll_fini(ddev); - free_irq(sdev->irq, ddev); - drm_dev_put(ddev); - - return 0; -} - -static int shmob_drm_probe(struct platform_device *pdev) -{ - struct shmob_drm_platform_data *pdata = pdev->dev.platform_data; - struct shmob_drm_device *sdev; - struct drm_device *ddev; - unsigned int i; - int ret; - - if (pdata == NULL) { - dev_err(&pdev->dev, "no platform data\n"); - return -EINVAL; - } - - /* - * Allocate and initialize the driver private data, I/O resources and - * clocks. - */ - sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL); - if (sdev == NULL) - return -ENOMEM; - - sdev->dev = &pdev->dev; - sdev->pdata = pdata; - spin_lock_init(&sdev->irq_lock); - - platform_set_drvdata(pdev, sdev); - - sdev->mmio = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(sdev->mmio)) - return PTR_ERR(sdev->mmio); - - ret = shmob_drm_setup_clocks(sdev, pdata->clk_source); - if (ret < 0) - return ret; - - ret = shmob_drm_init_interface(sdev); - if (ret < 0) - return ret; - - /* Allocate and initialize the DRM device. */ - ddev = drm_dev_alloc(&shmob_drm_driver, &pdev->dev); - if (IS_ERR(ddev)) - return PTR_ERR(ddev); - - sdev->ddev = ddev; - ddev->dev_private = sdev; - - ret = shmob_drm_modeset_init(sdev); - if (ret < 0) { - dev_err(&pdev->dev, "failed to initialize mode setting\n"); - goto err_free_drm_dev; - } - - for (i = 0; i < 4; ++i) { - ret = shmob_drm_plane_create(sdev, i); - if (ret < 0) { - dev_err(&pdev->dev, "failed to create plane %u\n", i); - goto err_modeset_cleanup; - } - } - - ret = drm_vblank_init(ddev, 1); - if (ret < 0) { - dev_err(&pdev->dev, "failed to initialize vblank\n"); - goto err_modeset_cleanup; - } - - ret = platform_get_irq(pdev, 0); - if (ret < 0) - goto err_modeset_cleanup; - sdev->irq = ret; - - ret = request_irq(sdev->irq, shmob_drm_irq, 0, ddev->driver->name, - ddev); - if (ret < 0) { - dev_err(&pdev->dev, "failed to install IRQ handler\n"); - goto err_modeset_cleanup; - } - - /* - * Register the DRM device with the core and the connectors with - * sysfs. - */ - ret = drm_dev_register(ddev, 0); - if (ret < 0) - goto err_irq_uninstall; - - return 0; - -err_irq_uninstall: - free_irq(sdev->irq, ddev); -err_modeset_cleanup: - drm_kms_helper_poll_fini(ddev); -err_free_drm_dev: - drm_dev_put(ddev); - - return ret; -} - -static struct platform_driver shmob_drm_platform_driver = { - .probe = shmob_drm_probe, - .remove = shmob_drm_remove, - .driver = { - .name = "shmob-drm", - .pm = &shmob_drm_pm_ops, - }, -}; - -drm_module_platform_driver(shmob_drm_platform_driver); - -MODULE_AUTHOR("Laurent Pinchart "); -MODULE_DESCRIPTION("Renesas SH Mobile DRM Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/shmobile/shmob_drm_drv.h deleted file mode 100644 index 4964ddd5ab7472..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * shmob_drm.h -- SH Mobile DRM driver - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#ifndef __SHMOB_DRM_DRV_H__ -#define __SHMOB_DRM_DRV_H__ - -#include -#include -#include - -#include "shmob_drm_crtc.h" - -struct clk; -struct device; -struct drm_device; - -struct shmob_drm_device { - struct device *dev; - const struct shmob_drm_platform_data *pdata; - - void __iomem *mmio; - struct clk *clock; - u32 lddckr; - u32 ldmt1r; - - unsigned int irq; - spinlock_t irq_lock; /* Protects hardware LDINTR register */ - - struct drm_device *ddev; - - struct shmob_drm_crtc crtc; - struct shmob_drm_encoder encoder; - struct shmob_drm_connector connector; -}; - -#endif /* __SHMOB_DRM_DRV_H__ */ diff --git a/drivers/gpu/drm/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/shmobile/shmob_drm_kms.c deleted file mode 100644 index 60a2c8d8a0d947..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_kms.c +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * shmob_drm_kms.c -- SH Mobile DRM Mode Setting - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#include -#include -#include -#include -#include -#include - -#include "shmob_drm_crtc.h" -#include "shmob_drm_drv.h" -#include "shmob_drm_kms.h" -#include "shmob_drm_regs.h" - -/* ----------------------------------------------------------------------------- - * Format helpers - */ - -static const struct shmob_drm_format_info shmob_drm_format_infos[] = { - { - .fourcc = DRM_FORMAT_RGB565, - .bpp = 16, - .yuv = false, - .lddfr = LDDFR_PKF_RGB16, - }, { - .fourcc = DRM_FORMAT_RGB888, - .bpp = 24, - .yuv = false, - .lddfr = LDDFR_PKF_RGB24, - }, { - .fourcc = DRM_FORMAT_ARGB8888, - .bpp = 32, - .yuv = false, - .lddfr = LDDFR_PKF_ARGB32, - }, { - .fourcc = DRM_FORMAT_NV12, - .bpp = 12, - .yuv = true, - .lddfr = LDDFR_CC | LDDFR_YF_420, - }, { - .fourcc = DRM_FORMAT_NV21, - .bpp = 12, - .yuv = true, - .lddfr = LDDFR_CC | LDDFR_YF_420, - }, { - .fourcc = DRM_FORMAT_NV16, - .bpp = 16, - .yuv = true, - .lddfr = LDDFR_CC | LDDFR_YF_422, - }, { - .fourcc = DRM_FORMAT_NV61, - .bpp = 16, - .yuv = true, - .lddfr = LDDFR_CC | LDDFR_YF_422, - }, { - .fourcc = DRM_FORMAT_NV24, - .bpp = 24, - .yuv = true, - .lddfr = LDDFR_CC | LDDFR_YF_444, - }, { - .fourcc = DRM_FORMAT_NV42, - .bpp = 24, - .yuv = true, - .lddfr = LDDFR_CC | LDDFR_YF_444, - }, -}; - -const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(shmob_drm_format_infos); ++i) { - if (shmob_drm_format_infos[i].fourcc == fourcc) - return &shmob_drm_format_infos[i]; - } - - return NULL; -} - -/* ----------------------------------------------------------------------------- - * Frame buffer - */ - -static struct drm_framebuffer * -shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - const struct shmob_drm_format_info *format; - - format = shmob_drm_format_info(mode_cmd->pixel_format); - if (format == NULL) { - dev_dbg(dev->dev, "unsupported pixel format %08x\n", - mode_cmd->pixel_format); - return ERR_PTR(-EINVAL); - } - - if (mode_cmd->pitches[0] & 7 || mode_cmd->pitches[0] >= 65536) { - dev_dbg(dev->dev, "invalid pitch value %u\n", - mode_cmd->pitches[0]); - return ERR_PTR(-EINVAL); - } - - if (format->yuv) { - unsigned int chroma_cpp = format->bpp == 24 ? 2 : 1; - - if (mode_cmd->pitches[1] != mode_cmd->pitches[0] * chroma_cpp) { - dev_dbg(dev->dev, - "luma and chroma pitches do not match\n"); - return ERR_PTR(-EINVAL); - } - } - - return drm_gem_fb_create(dev, file_priv, mode_cmd); -} - -static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = { - .fb_create = shmob_drm_fb_create, -}; - -int shmob_drm_modeset_init(struct shmob_drm_device *sdev) -{ - int ret; - - ret = drmm_mode_config_init(sdev->ddev); - if (ret) - return ret; - - shmob_drm_crtc_create(sdev); - shmob_drm_encoder_create(sdev); - shmob_drm_connector_create(sdev, &sdev->encoder.encoder); - - drm_kms_helper_poll_init(sdev->ddev); - - sdev->ddev->mode_config.min_width = 0; - sdev->ddev->mode_config.min_height = 0; - sdev->ddev->mode_config.max_width = 4095; - sdev->ddev->mode_config.max_height = 4095; - sdev->ddev->mode_config.funcs = &shmob_drm_mode_config_funcs; - - drm_helper_disable_unused_functions(sdev->ddev); - - return 0; -} diff --git a/drivers/gpu/drm/shmobile/shmob_drm_kms.h b/drivers/gpu/drm/shmobile/shmob_drm_kms.h deleted file mode 100644 index 0347b1fd2338a8..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_kms.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * shmob_drm_kms.h -- SH Mobile DRM Mode Setting - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#ifndef __SHMOB_DRM_KMS_H__ -#define __SHMOB_DRM_KMS_H__ - -#include - -struct drm_gem_dma_object; -struct shmob_drm_device; - -struct shmob_drm_format_info { - u32 fourcc; - unsigned int bpp; - bool yuv; - u32 lddfr; -}; - -const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc); - -int shmob_drm_modeset_init(struct shmob_drm_device *sdev); - -#endif /* __SHMOB_DRM_KMS_H__ */ diff --git a/drivers/gpu/drm/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/shmobile/shmob_drm_plane.c deleted file mode 100644 index 6c5f0cbe7d95b9..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_plane.c +++ /dev/null @@ -1,261 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * shmob_drm_plane.c -- SH Mobile DRM Planes - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#include -#include -#include -#include -#include -#include - -#include "shmob_drm_drv.h" -#include "shmob_drm_kms.h" -#include "shmob_drm_plane.h" -#include "shmob_drm_regs.h" - -struct shmob_drm_plane { - struct drm_plane plane; - unsigned int index; - unsigned int alpha; - - const struct shmob_drm_format_info *format; - unsigned long dma[2]; - - unsigned int src_x; - unsigned int src_y; - unsigned int crtc_x; - unsigned int crtc_y; - unsigned int crtc_w; - unsigned int crtc_h; -}; - -#define to_shmob_plane(p) container_of(p, struct shmob_drm_plane, plane) - -static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane, - struct drm_framebuffer *fb, - int x, int y) -{ - struct drm_gem_dma_object *gem; - unsigned int bpp; - - bpp = splane->format->yuv ? 8 : splane->format->bpp; - gem = drm_fb_dma_get_gem_obj(fb, 0); - splane->dma[0] = gem->dma_addr + fb->offsets[0] - + y * fb->pitches[0] + x * bpp / 8; - - if (splane->format->yuv) { - bpp = splane->format->bpp - 8; - gem = drm_fb_dma_get_gem_obj(fb, 1); - splane->dma[1] = gem->dma_addr + fb->offsets[1] - + y / (bpp == 4 ? 2 : 1) * fb->pitches[1] - + x * (bpp == 16 ? 2 : 1); - } -} - -static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane, - struct drm_framebuffer *fb) -{ - struct shmob_drm_device *sdev = splane->plane.dev->dev_private; - u32 format; - - /* TODO: Support ROP3 mode */ - format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT); - - switch (splane->format->fourcc) { - case DRM_FORMAT_RGB565: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV61: - case DRM_FORMAT_NV42: - format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW; - break; - case DRM_FORMAT_RGB888: - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV24: - format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB; - break; - case DRM_FORMAT_ARGB8888: - default: - format |= LDBBSIFR_SWPL; - break; - } - - switch (splane->format->fourcc) { - case DRM_FORMAT_RGB565: - format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16; - break; - case DRM_FORMAT_RGB888: - format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24; - break; - case DRM_FORMAT_ARGB8888: - format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32; - break; - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420; - break; - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV61: - format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422; - break; - case DRM_FORMAT_NV24: - case DRM_FORMAT_NV42: - format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444; - break; - } - -#define plane_reg_dump(sdev, splane, reg) \ - dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \ - splane->index, #reg, \ - lcdc_read(sdev, reg(splane->index)), \ - lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET)) - - plane_reg_dump(sdev, splane, LDBnBSIFR); - plane_reg_dump(sdev, splane, LDBnBSSZR); - plane_reg_dump(sdev, splane, LDBnBLOCR); - plane_reg_dump(sdev, splane, LDBnBSMWR); - plane_reg_dump(sdev, splane, LDBnBSAYR); - plane_reg_dump(sdev, splane, LDBnBSACR); - - lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index)); - dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index, - "LDBCR", lcdc_read(sdev, LDBCR)); - - lcdc_write(sdev, LDBnBSIFR(splane->index), format); - - lcdc_write(sdev, LDBnBSSZR(splane->index), - (splane->crtc_h << LDBBSSZR_BVSS_SHIFT) | - (splane->crtc_w << LDBBSSZR_BHSS_SHIFT)); - lcdc_write(sdev, LDBnBLOCR(splane->index), - (splane->crtc_y << LDBBLOCR_CVLC_SHIFT) | - (splane->crtc_x << LDBBLOCR_CHLC_SHIFT)); - lcdc_write(sdev, LDBnBSMWR(splane->index), - fb->pitches[0] << LDBBSMWR_BSMW_SHIFT); - - shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y); - - lcdc_write(sdev, LDBnBSAYR(splane->index), splane->dma[0]); - if (splane->format->yuv) - lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]); - - lcdc_write(sdev, LDBCR, - LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index)); - dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index, - "LDBCR", lcdc_read(sdev, LDBCR)); - - plane_reg_dump(sdev, splane, LDBnBSIFR); - plane_reg_dump(sdev, splane, LDBnBSSZR); - plane_reg_dump(sdev, splane, LDBnBLOCR); - plane_reg_dump(sdev, splane, LDBnBSMWR); - plane_reg_dump(sdev, splane, LDBnBSAYR); - plane_reg_dump(sdev, splane, LDBnBSACR); -} - -void shmob_drm_plane_setup(struct drm_plane *plane) -{ - struct shmob_drm_plane *splane = to_shmob_plane(plane); - - if (plane->fb == NULL) - return; - - __shmob_drm_plane_setup(splane, plane->fb); -} - -static int -shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h, - struct drm_modeset_acquire_ctx *ctx) -{ - struct shmob_drm_plane *splane = to_shmob_plane(plane); - struct shmob_drm_device *sdev = plane->dev->dev_private; - const struct shmob_drm_format_info *format; - - format = shmob_drm_format_info(fb->format->format); - if (format == NULL) { - dev_dbg(sdev->dev, "update_plane: unsupported format %08x\n", - fb->format->format); - return -EINVAL; - } - - if (src_w >> 16 != crtc_w || src_h >> 16 != crtc_h) { - dev_dbg(sdev->dev, "%s: scaling not supported\n", __func__); - return -EINVAL; - } - - splane->format = format; - - splane->src_x = src_x >> 16; - splane->src_y = src_y >> 16; - splane->crtc_x = crtc_x; - splane->crtc_y = crtc_y; - splane->crtc_w = crtc_w; - splane->crtc_h = crtc_h; - - __shmob_drm_plane_setup(splane, fb); - return 0; -} - -static int shmob_drm_plane_disable(struct drm_plane *plane, - struct drm_modeset_acquire_ctx *ctx) -{ - struct shmob_drm_plane *splane = to_shmob_plane(plane); - struct shmob_drm_device *sdev = plane->dev->dev_private; - - splane->format = NULL; - - lcdc_write(sdev, LDBnBSIFR(splane->index), 0); - return 0; -} - -static void shmob_drm_plane_destroy(struct drm_plane *plane) -{ - drm_plane_force_disable(plane); - drm_plane_cleanup(plane); -} - -static const struct drm_plane_funcs shmob_drm_plane_funcs = { - .update_plane = shmob_drm_plane_update, - .disable_plane = shmob_drm_plane_disable, - .destroy = shmob_drm_plane_destroy, -}; - -static const uint32_t formats[] = { - DRM_FORMAT_RGB565, - DRM_FORMAT_RGB888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_NV12, - DRM_FORMAT_NV21, - DRM_FORMAT_NV16, - DRM_FORMAT_NV61, - DRM_FORMAT_NV24, - DRM_FORMAT_NV42, -}; - -int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index) -{ - struct shmob_drm_plane *splane; - int ret; - - splane = devm_kzalloc(sdev->dev, sizeof(*splane), GFP_KERNEL); - if (splane == NULL) - return -ENOMEM; - - splane->index = index; - splane->alpha = 255; - - ret = drm_universal_plane_init(sdev->ddev, &splane->plane, 1, - &shmob_drm_plane_funcs, - formats, ARRAY_SIZE(formats), NULL, - DRM_PLANE_TYPE_OVERLAY, NULL); - - return ret; -} diff --git a/drivers/gpu/drm/shmobile/shmob_drm_plane.h b/drivers/gpu/drm/shmobile/shmob_drm_plane.h deleted file mode 100644 index e72b21a4288fc2..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_plane.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * shmob_drm_plane.h -- SH Mobile DRM Planes - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#ifndef __SHMOB_DRM_PLANE_H__ -#define __SHMOB_DRM_PLANE_H__ - -struct drm_plane; -struct shmob_drm_device; - -int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index); -void shmob_drm_plane_setup(struct drm_plane *plane); - -#endif /* __SHMOB_DRM_PLANE_H__ */ diff --git a/drivers/gpu/drm/shmobile/shmob_drm_regs.h b/drivers/gpu/drm/shmobile/shmob_drm_regs.h deleted file mode 100644 index 058533685c4cd0..00000000000000 --- a/drivers/gpu/drm/shmobile/shmob_drm_regs.h +++ /dev/null @@ -1,310 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * shmob_drm_regs.h -- SH Mobile DRM registers - * - * Copyright (C) 2012 Renesas Electronics Corporation - * - * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - */ - -#ifndef __SHMOB_DRM_REGS_H__ -#define __SHMOB_DRM_REGS_H__ - -#include -#include - -#include "shmob_drm_drv.h" - -/* Register definitions */ -#define LDDCKPAT1R 0x400 -#define LDDCKPAT2R 0x404 -#define LDDCKR 0x410 -#define LDDCKR_ICKSEL_BUS (0 << 16) -#define LDDCKR_ICKSEL_MIPI (1 << 16) -#define LDDCKR_ICKSEL_HDMI (2 << 16) -#define LDDCKR_ICKSEL_EXT (3 << 16) -#define LDDCKR_ICKSEL_MASK (7 << 16) -#define LDDCKR_MOSEL (1 << 6) -#define LDDCKSTPR 0x414 -#define LDDCKSTPR_DCKSTS (1 << 16) -#define LDDCKSTPR_DCKSTP (1 << 0) -#define LDMT1R 0x418 -#define LDMT1R_VPOL (1 << 28) -#define LDMT1R_HPOL (1 << 27) -#define LDMT1R_DWPOL (1 << 26) -#define LDMT1R_DIPOL (1 << 25) -#define LDMT1R_DAPOL (1 << 24) -#define LDMT1R_HSCNT (1 << 17) -#define LDMT1R_DWCNT (1 << 16) -#define LDMT1R_IFM (1 << 12) -#define LDMT1R_MIFTYP_RGB8 (0x0 << 0) -#define LDMT1R_MIFTYP_RGB9 (0x4 << 0) -#define LDMT1R_MIFTYP_RGB12A (0x5 << 0) -#define LDMT1R_MIFTYP_RGB12B (0x6 << 0) -#define LDMT1R_MIFTYP_RGB16 (0x7 << 0) -#define LDMT1R_MIFTYP_RGB18 (0xa << 0) -#define LDMT1R_MIFTYP_RGB24 (0xb << 0) -#define LDMT1R_MIFTYP_YCBCR (0xf << 0) -#define LDMT1R_MIFTYP_SYS8A (0x0 << 0) -#define LDMT1R_MIFTYP_SYS8B (0x1 << 0) -#define LDMT1R_MIFTYP_SYS8C (0x2 << 0) -#define LDMT1R_MIFTYP_SYS8D (0x3 << 0) -#define LDMT1R_MIFTYP_SYS9 (0x4 << 0) -#define LDMT1R_MIFTYP_SYS12 (0x5 << 0) -#define LDMT1R_MIFTYP_SYS16A (0x7 << 0) -#define LDMT1R_MIFTYP_SYS16B (0x8 << 0) -#define LDMT1R_MIFTYP_SYS16C (0x9 << 0) -#define LDMT1R_MIFTYP_SYS18 (0xa << 0) -#define LDMT1R_MIFTYP_SYS24 (0xb << 0) -#define LDMT1R_MIFTYP_MASK (0xf << 0) -#define LDMT2R 0x41c -#define LDMT2R_CSUP_MASK (7 << 26) -#define LDMT2R_CSUP_SHIFT 26 -#define LDMT2R_RSV (1 << 25) -#define LDMT2R_VSEL (1 << 24) -#define LDMT2R_WCSC_MASK (0xff << 16) -#define LDMT2R_WCSC_SHIFT 16 -#define LDMT2R_WCEC_MASK (0xff << 8) -#define LDMT2R_WCEC_SHIFT 8 -#define LDMT2R_WCLW_MASK (0xff << 0) -#define LDMT2R_WCLW_SHIFT 0 -#define LDMT3R 0x420 -#define LDMT3R_RDLC_MASK (0x3f << 24) -#define LDMT3R_RDLC_SHIFT 24 -#define LDMT3R_RCSC_MASK (0xff << 16) -#define LDMT3R_RCSC_SHIFT 16 -#define LDMT3R_RCEC_MASK (0xff << 8) -#define LDMT3R_RCEC_SHIFT 8 -#define LDMT3R_RCLW_MASK (0xff << 0) -#define LDMT3R_RCLW_SHIFT 0 -#define LDDFR 0x424 -#define LDDFR_CF1 (1 << 18) -#define LDDFR_CF0 (1 << 17) -#define LDDFR_CC (1 << 16) -#define LDDFR_YF_420 (0 << 8) -#define LDDFR_YF_422 (1 << 8) -#define LDDFR_YF_444 (2 << 8) -#define LDDFR_YF_MASK (3 << 8) -#define LDDFR_PKF_ARGB32 (0x00 << 0) -#define LDDFR_PKF_RGB16 (0x03 << 0) -#define LDDFR_PKF_RGB24 (0x0b << 0) -#define LDDFR_PKF_MASK (0x1f << 0) -#define LDSM1R 0x428 -#define LDSM1R_OS (1 << 0) -#define LDSM2R 0x42c -#define LDSM2R_OSTRG (1 << 0) -#define LDSA1R 0x430 -#define LDSA2R 0x434 -#define LDMLSR 0x438 -#define LDWBFR 0x43c -#define LDWBCNTR 0x440 -#define LDWBAR 0x444 -#define LDHCNR 0x448 -#define LDHSYNR 0x44c -#define LDVLNR 0x450 -#define LDVSYNR 0x454 -#define LDHPDR 0x458 -#define LDVPDR 0x45c -#define LDPMR 0x460 -#define LDPMR_LPS (3 << 0) -#define LDINTR 0x468 -#define LDINTR_FE (1 << 10) -#define LDINTR_VSE (1 << 9) -#define LDINTR_VEE (1 << 8) -#define LDINTR_FS (1 << 2) -#define LDINTR_VSS (1 << 1) -#define LDINTR_VES (1 << 0) -#define LDINTR_STATUS_MASK (0xff << 0) -#define LDSR 0x46c -#define LDSR_MSS (1 << 10) -#define LDSR_MRS (1 << 8) -#define LDSR_AS (1 << 1) -#define LDCNT1R 0x470 -#define LDCNT1R_DE (1 << 0) -#define LDCNT2R 0x474 -#define LDCNT2R_BR (1 << 8) -#define LDCNT2R_MD (1 << 3) -#define LDCNT2R_SE (1 << 2) -#define LDCNT2R_ME (1 << 1) -#define LDCNT2R_DO (1 << 0) -#define LDRCNTR 0x478 -#define LDRCNTR_SRS (1 << 17) -#define LDRCNTR_SRC (1 << 16) -#define LDRCNTR_MRS (1 << 1) -#define LDRCNTR_MRC (1 << 0) -#define LDDDSR 0x47c -#define LDDDSR_LS (1 << 2) -#define LDDDSR_WS (1 << 1) -#define LDDDSR_BS (1 << 0) -#define LDHAJR 0x4a0 - -#define LDDWD0R 0x800 -#define LDDWDxR_WDACT (1 << 28) -#define LDDWDxR_RSW (1 << 24) -#define LDDRDR 0x840 -#define LDDRDR_RSR (1 << 24) -#define LDDRDR_DRD_MASK (0x3ffff << 0) -#define LDDWAR 0x900 -#define LDDWAR_WA (1 << 0) -#define LDDRAR 0x904 -#define LDDRAR_RA (1 << 0) - -#define LDBCR 0xb00 -#define LDBCR_UPC(n) (1 << ((n) + 16)) -#define LDBCR_UPF(n) (1 << ((n) + 8)) -#define LDBCR_UPD(n) (1 << ((n) + 0)) -#define LDBnBSIFR(n) (0xb20 + (n) * 0x20 + 0x00) -#define LDBBSIFR_EN (1 << 31) -#define LDBBSIFR_VS (1 << 29) -#define LDBBSIFR_BRSEL (1 << 28) -#define LDBBSIFR_MX (1 << 27) -#define LDBBSIFR_MY (1 << 26) -#define LDBBSIFR_CV3 (3 << 24) -#define LDBBSIFR_CV2 (2 << 24) -#define LDBBSIFR_CV1 (1 << 24) -#define LDBBSIFR_CV0 (0 << 24) -#define LDBBSIFR_CV_MASK (3 << 24) -#define LDBBSIFR_LAY_MASK (0xff << 16) -#define LDBBSIFR_LAY_SHIFT 16 -#define LDBBSIFR_ROP3_MASK (0xff << 16) -#define LDBBSIFR_ROP3_SHIFT 16 -#define LDBBSIFR_AL_PL8 (3 << 14) -#define LDBBSIFR_AL_PL1 (2 << 14) -#define LDBBSIFR_AL_PK (1 << 14) -#define LDBBSIFR_AL_1 (0 << 14) -#define LDBBSIFR_AL_MASK (3 << 14) -#define LDBBSIFR_SWPL (1 << 10) -#define LDBBSIFR_SWPW (1 << 9) -#define LDBBSIFR_SWPB (1 << 8) -#define LDBBSIFR_RY (1 << 7) -#define LDBBSIFR_CHRR_420 (2 << 0) -#define LDBBSIFR_CHRR_422 (1 << 0) -#define LDBBSIFR_CHRR_444 (0 << 0) -#define LDBBSIFR_RPKF_ARGB32 (0x00 << 0) -#define LDBBSIFR_RPKF_RGB16 (0x03 << 0) -#define LDBBSIFR_RPKF_RGB24 (0x0b << 0) -#define LDBBSIFR_RPKF_MASK (0x1f << 0) -#define LDBnBSSZR(n) (0xb20 + (n) * 0x20 + 0x04) -#define LDBBSSZR_BVSS_MASK (0xfff << 16) -#define LDBBSSZR_BVSS_SHIFT 16 -#define LDBBSSZR_BHSS_MASK (0xfff << 0) -#define LDBBSSZR_BHSS_SHIFT 0 -#define LDBnBLOCR(n) (0xb20 + (n) * 0x20 + 0x08) -#define LDBBLOCR_CVLC_MASK (0xfff << 16) -#define LDBBLOCR_CVLC_SHIFT 16 -#define LDBBLOCR_CHLC_MASK (0xfff << 0) -#define LDBBLOCR_CHLC_SHIFT 0 -#define LDBnBSMWR(n) (0xb20 + (n) * 0x20 + 0x0c) -#define LDBBSMWR_BSMWA_MASK (0xffff << 16) -#define LDBBSMWR_BSMWA_SHIFT 16 -#define LDBBSMWR_BSMW_MASK (0xffff << 0) -#define LDBBSMWR_BSMW_SHIFT 0 -#define LDBnBSAYR(n) (0xb20 + (n) * 0x20 + 0x10) -#define LDBBSAYR_FG1A_MASK (0xff << 24) -#define LDBBSAYR_FG1A_SHIFT 24 -#define LDBBSAYR_FG1R_MASK (0xff << 16) -#define LDBBSAYR_FG1R_SHIFT 16 -#define LDBBSAYR_FG1G_MASK (0xff << 8) -#define LDBBSAYR_FG1G_SHIFT 8 -#define LDBBSAYR_FG1B_MASK (0xff << 0) -#define LDBBSAYR_FG1B_SHIFT 0 -#define LDBnBSACR(n) (0xb20 + (n) * 0x20 + 0x14) -#define LDBBSACR_FG2A_MASK (0xff << 24) -#define LDBBSACR_FG2A_SHIFT 24 -#define LDBBSACR_FG2R_MASK (0xff << 16) -#define LDBBSACR_FG2R_SHIFT 16 -#define LDBBSACR_FG2G_MASK (0xff << 8) -#define LDBBSACR_FG2G_SHIFT 8 -#define LDBBSACR_FG2B_MASK (0xff << 0) -#define LDBBSACR_FG2B_SHIFT 0 -#define LDBnBSAAR(n) (0xb20 + (n) * 0x20 + 0x18) -#define LDBBSAAR_AP_MASK (0xff << 24) -#define LDBBSAAR_AP_SHIFT 24 -#define LDBBSAAR_R_MASK (0xff << 16) -#define LDBBSAAR_R_SHIFT 16 -#define LDBBSAAR_GY_MASK (0xff << 8) -#define LDBBSAAR_GY_SHIFT 8 -#define LDBBSAAR_B_MASK (0xff << 0) -#define LDBBSAAR_B_SHIFT 0 -#define LDBnBPPCR(n) (0xb20 + (n) * 0x20 + 0x1c) -#define LDBBPPCR_AP_MASK (0xff << 24) -#define LDBBPPCR_AP_SHIFT 24 -#define LDBBPPCR_R_MASK (0xff << 16) -#define LDBBPPCR_R_SHIFT 16 -#define LDBBPPCR_GY_MASK (0xff << 8) -#define LDBBPPCR_GY_SHIFT 8 -#define LDBBPPCR_B_MASK (0xff << 0) -#define LDBBPPCR_B_SHIFT 0 -#define LDBnBBGCL(n) (0xb10 + (n) * 0x04) -#define LDBBBGCL_BGA_MASK (0xff << 24) -#define LDBBBGCL_BGA_SHIFT 24 -#define LDBBBGCL_BGR_MASK (0xff << 16) -#define LDBBBGCL_BGR_SHIFT 16 -#define LDBBBGCL_BGG_MASK (0xff << 8) -#define LDBBBGCL_BGG_SHIFT 8 -#define LDBBBGCL_BGB_MASK (0xff << 0) -#define LDBBBGCL_BGB_SHIFT 0 - -#define LCDC_SIDE_B_OFFSET 0x1000 -#define LCDC_MIRROR_OFFSET 0x2000 - -static inline bool lcdc_is_banked(u32 reg) -{ - switch (reg) { - case LDMT1R: - case LDMT2R: - case LDMT3R: - case LDDFR: - case LDSM1R: - case LDSA1R: - case LDSA2R: - case LDMLSR: - case LDWBFR: - case LDWBCNTR: - case LDWBAR: - case LDHCNR: - case LDHSYNR: - case LDVLNR: - case LDVSYNR: - case LDHPDR: - case LDVPDR: - case LDHAJR: - return true; - default: - return reg >= LDBnBBGCL(0) && reg <= LDBnBPPCR(3); - } -} - -static inline void lcdc_write_mirror(struct shmob_drm_device *sdev, u32 reg, - u32 data) -{ - iowrite32(data, sdev->mmio + reg + LCDC_MIRROR_OFFSET); -} - -static inline void lcdc_write(struct shmob_drm_device *sdev, u32 reg, u32 data) -{ - iowrite32(data, sdev->mmio + reg); - if (lcdc_is_banked(reg)) - iowrite32(data, sdev->mmio + reg + LCDC_SIDE_B_OFFSET); -} - -static inline u32 lcdc_read(struct shmob_drm_device *sdev, u32 reg) -{ - return ioread32(sdev->mmio + reg); -} - -static inline int lcdc_wait_bit(struct shmob_drm_device *sdev, u32 reg, - u32 mask, u32 until) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(5); - - while ((lcdc_read(sdev, reg) & mask) != until) { - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - cpu_relax(); - } - - return 0; -} - -#endif /* __SHMOB_DRM_REGS_H__ */ From patchwork Fri Jan 13 06:23:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642555 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9D6FC61DB3 for ; Fri, 13 Jan 2023 06:26:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240731AbjAMG0Y (ORCPT ); Fri, 13 Jan 2023 01:26:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234761AbjAMGYg (ORCPT ); Fri, 13 Jan 2023 01:24:36 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 498495C1E9; Thu, 12 Jan 2023 22:24:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=erzrm4Ty5idHGyu1jH564OsyzlBO2Da+dsAYs2Uai6g=; b=PetC+G54fA2MHOPn5yey+DdmCl R14MH27shd3orjHYKWEFGSdK5sHDVqWEit9ROBI9QtItF8PeoTYlNLc27qCKd4mBlGl8jANIltvc4 5uvf/bF6LMZMC3fRULQGtDiirUzaHq9DinFdafA4frKBNm+yAMh94U6OnJ7LGL0XptNiPpS5DsIWd GO3TjAdGZQt0xM+O6jEYTtFY/OIcQA9dsgy6SBP+X4K3WFPlg8cv17nlZY99em0nT73cU9pNa99ua b3uzExO4rYmov4NBJ22hBeTV6aNAU0ZwIK9zJ00YufRoOb+tROzO9aXzsvT/iQZ6VeSKM1biDvQti x8bvB2Pg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDTu-000lTC-Dy; Fri, 13 Jan 2023 06:24:04 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 05/22] sound: remove sh-specific sounds/soc/sh drivers Date: Fri, 13 Jan 2023 07:23:22 +0100 Message-Id: <20230113062339.1909087-6-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Now that arch/sh is removed these drivers are dead code. Signed-off-by: Christoph Hellwig --- sound/soc/sh/Kconfig | 44 -- sound/soc/sh/Makefile | 16 - sound/soc/sh/dma-sh7760.c | 334 ---------------- sound/soc/sh/fsi.c | 9 - sound/soc/sh/hac.c | 345 ---------------- sound/soc/sh/migor.c | 205 ---------- sound/soc/sh/sh7760-ac97.c | 72 ---- sound/soc/sh/siu.h | 180 --------- sound/soc/sh/siu_dai.c | 799 ------------------------------------- sound/soc/sh/siu_pcm.c | 553 ------------------------- sound/soc/sh/ssi.c | 403 ------------------- 11 files changed, 2960 deletions(-) delete mode 100644 sound/soc/sh/dma-sh7760.c delete mode 100644 sound/soc/sh/hac.c delete mode 100644 sound/soc/sh/migor.c delete mode 100644 sound/soc/sh/sh7760-ac97.c delete mode 100644 sound/soc/sh/siu.h delete mode 100644 sound/soc/sh/siu_dai.c delete mode 100644 sound/soc/sh/siu_pcm.c delete mode 100644 sound/soc/sh/ssi.c diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 793a0326f32b46..4367927b81df20 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -2,25 +2,10 @@ menu "SoC Audio support for Renesas SoCs" depends on ARCH_RENESAS || COMPILE_TEST -config SND_SOC_PCM_SH7760 - tristate "SoC Audio support for Renesas SH7760" - depends on CPU_SUBTYPE_SH7760 && SH_DMABRG - help - Enable this option for SH7760 AC97/I2S audio support. - - ## ## Audio unit modules ## -config SND_SOC_SH4_HAC - tristate - select AC97_BUS - select SND_SOC_AC97_BUS - -config SND_SOC_SH4_SSI - tristate - config SND_SOC_SH4_FSI tristate "SH4 FSI support" depends on COMMON_CLK @@ -28,14 +13,6 @@ config SND_SOC_SH4_FSI help This option enables FSI sound support -config SND_SOC_SH4_SIU - tristate - depends on ARCH_SHMOBILE && HAVE_CLK - depends on DMADEVICES - select DMA_ENGINE - select SH_DMAE - select FW_LOADER - config SND_SOC_RCAR tristate "R-Car series SRU/SCU/SSIU/SSI support" depends on COMMON_CLK @@ -51,25 +28,4 @@ config SND_SOC_RZ help This option enables RZ/G2L SSIF-2 sound support. -## -## Boards -## - -config SND_SH7760_AC97 - tristate "SH7760 AC97 sound support" - depends on CPU_SUBTYPE_SH7760 && SND_SOC_PCM_SH7760 - select SND_SOC_SH4_HAC - select SND_SOC_AC97_CODEC - help - This option enables generic sound support for the first - AC97 unit of the SH7760. - -config SND_SIU_MIGOR - tristate "SIU sound support on Migo-R" - depends on SH_MIGOR && I2C - select SND_SOC_SH4_SIU - select SND_SOC_WM8978 - help - This option enables sound support for the SH7722 Migo-R board - endmenu diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile index f6fd79948f6ae9..c308dda887e633 100644 --- a/sound/soc/sh/Makefile +++ b/sound/soc/sh/Makefile @@ -1,28 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 -## DMA engines -snd-soc-dma-sh7760-objs := dma-sh7760.o -obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o ## audio units found on some SH-4 -snd-soc-hac-objs := hac.o -snd-soc-ssi-objs := ssi.o snd-soc-fsi-objs := fsi.o -snd-soc-siu-objs := siu_pcm.o siu_dai.o -obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o -obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o -obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o ## audio units for R-Car obj-$(CONFIG_SND_SOC_RCAR) += rcar/ -## boards -snd-soc-sh7760-ac97-objs := sh7760-ac97.o -snd-soc-migor-objs := migor.o - -obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o -obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o - # RZ/G2L snd-soc-rz-ssi-objs := rz-ssi.o obj-$(CONFIG_SND_SOC_RZ) += snd-soc-rz-ssi.o diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c deleted file mode 100644 index 121e48f984c50c..00000000000000 --- a/sound/soc/sh/dma-sh7760.c +++ /dev/null @@ -1,334 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// SH7760 ("camelot") DMABRG audio DMA unit support -// -// Copyright (C) 2007 Manuel Lauss -// -// The SH7760 DMABRG provides 4 dma channels (2x rec, 2x play), which -// trigger an interrupt when one half of the programmed transfer size -// has been xmitted. -// -// FIXME: little-endian only for now - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* registers and bits */ -#define BRGATXSAR 0x00 -#define BRGARXDAR 0x04 -#define BRGATXTCR 0x08 -#define BRGARXTCR 0x0C -#define BRGACR 0x10 -#define BRGATXTCNT 0x14 -#define BRGARXTCNT 0x18 - -#define ACR_RAR (1 << 18) -#define ACR_RDS (1 << 17) -#define ACR_RDE (1 << 16) -#define ACR_TAR (1 << 2) -#define ACR_TDS (1 << 1) -#define ACR_TDE (1 << 0) - -/* receiver/transmitter data alignment */ -#define ACR_RAM_NONE (0 << 24) -#define ACR_RAM_4BYTE (1 << 24) -#define ACR_RAM_2WORD (2 << 24) -#define ACR_TAM_NONE (0 << 8) -#define ACR_TAM_4BYTE (1 << 8) -#define ACR_TAM_2WORD (2 << 8) - - -struct camelot_pcm { - unsigned long mmio; /* DMABRG audio channel control reg MMIO */ - unsigned int txid; /* ID of first DMABRG IRQ for this unit */ - - struct snd_pcm_substream *tx_ss; - unsigned long tx_period_size; - unsigned int tx_period; - - struct snd_pcm_substream *rx_ss; - unsigned long rx_period_size; - unsigned int rx_period; - -} cam_pcm_data[2] = { - { - .mmio = 0xFE3C0040, - .txid = DMABRGIRQ_A0TXF, - }, - { - .mmio = 0xFE3C0060, - .txid = DMABRGIRQ_A1TXF, - }, -}; - -#define BRGREG(x) (*(unsigned long *)(cam->mmio + (x))) - -/* - * set a minimum of 16kb per period, to avoid interrupt-"storm" and - * resulting skipping. In general, the bigger the minimum size, the - * better for overall system performance. (The SH7760 is a puny CPU - * with a slow SDRAM interface and poor internal bus bandwidth, - * *especially* when the LCDC is active). The minimum for the DMAC - * is 8 bytes; 16kbytes are enough to get skip-free playback of a - * 44kHz/16bit/stereo MP3 on a lightly loaded system, and maintain - * reasonable responsiveness in MPlayer. - */ -#define DMABRG_PERIOD_MIN 16 * 1024 -#define DMABRG_PERIOD_MAX 0x03fffffc -#define DMABRG_PREALLOC_BUFFER 32 * 1024 -#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 - -static const struct snd_pcm_hardware camelot_pcm_hardware = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_BATCH), - .buffer_bytes_max = DMABRG_PERIOD_MAX, - .period_bytes_min = DMABRG_PERIOD_MIN, - .period_bytes_max = DMABRG_PERIOD_MAX / 2, - .periods_min = 2, - .periods_max = 2, - .fifo_size = 128, -}; - -static void camelot_txdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->tx_period ^= 1; - snd_pcm_period_elapsed(cam->tx_ss); -} - -static void camelot_rxdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->rx_period ^= 1; - snd_pcm_period_elapsed(cam->rx_ss); -} - -static int camelot_pcm_open(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int ret, dmairq; - - snd_soc_set_runtime_hwparams(substream, &camelot_pcm_hardware); - - /* DMABRG buffer half/full events */ - dmairq = (recv) ? cam->txid + 2 : cam->txid; - if (recv) { - cam->rx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - asoc_rtd_to_cpu(rtd, 0)->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam); - } else { - cam->tx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_txdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - asoc_rtd_to_cpu(rtd, 0)->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam); - } - return 0; -} - -static int camelot_pcm_close(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int dmairq; - - dmairq = (recv) ? cam->txid + 2 : cam->txid; - - if (recv) - cam->rx_ss = NULL; - else - cam->tx_ss = NULL; - - dmabrg_free_irq(dmairq + 1); - dmabrg_free_irq(dmairq); - - return 0; -} - -static int camelot_hw_params(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - - if (recv) { - cam->rx_period_size = params_period_bytes(hw_params); - cam->rx_period = 0; - } else { - cam->tx_period_size = params_period_bytes(hw_params); - cam->tx_period = 0; - } - return 0; -} - -static int camelot_prepare(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - - pr_debug("PCM data: addr 0x%08lx len %d\n", - (u32)runtime->dma_addr, runtime->dma_bytes); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - BRGREG(BRGATXSAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGATXTCR) = runtime->dma_bytes; - } else { - BRGREG(BRGARXDAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGARXTCR) = runtime->dma_bytes; - } - - return 0; -} - -static inline void dmabrg_play_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: XFER start, auto-addr-reload */ - BRGREG(BRGACR) = acr | ACR_TDE | ACR_TAR | ACR_TAM_2WORD; -} - -static inline void dmabrg_play_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data transmission */ - BRGREG(BRGACR) = acr | ACR_TDS; -} - -static inline void dmabrg_rec_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: recv start, auto-reload */ - BRGREG(BRGACR) = acr | ACR_RDE | ACR_RAR | ACR_RAM_2WORD; -} - -static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data receiver */ - BRGREG(BRGACR) = acr | ACR_RDS; -} - -static int camelot_trigger(struct snd_soc_component *component, - struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (recv) - dmabrg_rec_dma_start(cam); - else - dmabrg_play_dma_start(cam); - break; - case SNDRV_PCM_TRIGGER_STOP: - if (recv) - dmabrg_rec_dma_stop(cam); - else - dmabrg_play_dma_stop(cam); - break; - default: - return -EINVAL; - } - - return 0; -} - -static snd_pcm_uframes_t camelot_pos(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - unsigned long pos; - - /* cannot use the DMABRG pointer register: under load, by the - * time ALSA comes around to read the register, it is already - * far ahead (or worse, already done with the fragment) of the - * position at the time the IRQ was triggered, which results in - * fast-playback sound in my test application (ScummVM) - */ - if (recv) - pos = cam->rx_period ? cam->rx_period_size : 0; - else - pos = cam->tx_period ? cam->tx_period_size : 0; - - return bytes_to_frames(runtime, pos); -} - -static int camelot_pcm_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) -{ - struct snd_pcm *pcm = rtd->pcm; - - /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel - * in MMAP mode (i.e. aplay -M) - */ - snd_pcm_set_managed_buffer_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - NULL, - DMABRG_PREALLOC_BUFFER, DMABRG_PREALLOC_BUFFER_MAX); - - return 0; -} - -static const struct snd_soc_component_driver sh7760_soc_component = { - .open = camelot_pcm_open, - .close = camelot_pcm_close, - .hw_params = camelot_hw_params, - .prepare = camelot_prepare, - .trigger = camelot_trigger, - .pointer = camelot_pos, - .pcm_construct = camelot_pcm_new, -}; - -static int sh7760_soc_platform_probe(struct platform_device *pdev) -{ - return devm_snd_soc_register_component(&pdev->dev, &sh7760_soc_component, - NULL, 0); -} - -static struct platform_driver sh7760_pcm_driver = { - .driver = { - .name = "sh7760-pcm-audio", - }, - - .probe = sh7760_soc_platform_probe, -}; - -module_platform_driver(sh7760_pcm_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index f3edc2e3d9d7c4..c599070f2210f4 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1372,16 +1372,7 @@ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct dev { int is_play = fsi_stream_is_play(fsi, io); -#ifdef CONFIG_SUPERH - dma_cap_mask_t mask; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - io->chan = dma_request_channel(mask, shdma_chan_filter, - (void *)io->dma_id); -#else io->chan = dma_request_slave_channel(dev, is_play ? "tx" : "rx"); -#endif if (io->chan) { struct dma_slave_config cfg = {}; int ret; diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c deleted file mode 100644 index 46d145cbaf2970..00000000000000 --- a/sound/soc/sh/hac.c +++ /dev/null @@ -1,345 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Hitachi Audio Controller (AC97) support for SH7760/SH7780 -// -// Copyright (c) 2007 Manuel Lauss -// -// dont forget to set IPSEL/OMSEL register bits (in your board code) to -// enable HAC output pins! - -/* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only - * the FIRST can be used since ASoC does not pass any information to the - * ac97_read/write() functions regarding WHICH unit to use. You'll have - * to edit the code a bit to use the other AC97 unit. --mlau - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* regs and bits */ -#define HACCR 0x08 -#define HACCSAR 0x20 -#define HACCSDR 0x24 -#define HACPCML 0x28 -#define HACPCMR 0x2C -#define HACTIER 0x50 -#define HACTSR 0x54 -#define HACRIER 0x58 -#define HACRSR 0x5C -#define HACACR 0x60 - -#define CR_CR (1 << 15) /* "codec-ready" indicator */ -#define CR_CDRT (1 << 11) /* cold reset */ -#define CR_WMRT (1 << 10) /* warm reset */ -#define CR_B9 (1 << 9) /* the mysterious "bit 9" */ -#define CR_ST (1 << 5) /* AC97 link start bit */ - -#define CSAR_RD (1 << 19) /* AC97 data read bit */ -#define CSAR_WR (0) - -#define TSR_CMDAMT (1 << 31) -#define TSR_CMDDMT (1 << 30) - -#define RSR_STARY (1 << 22) -#define RSR_STDRY (1 << 21) - -#define ACR_DMARX16 (1 << 30) -#define ACR_DMATX16 (1 << 29) -#define ACR_TX12ATOM (1 << 26) -#define ACR_DMARX20 ((1 << 24) | (1 << 22)) -#define ACR_DMATX20 ((1 << 23) | (1 << 21)) - -#define CSDR_SHIFT 4 -#define CSDR_MASK (0xffff << CSDR_SHIFT) -#define CSAR_SHIFT 12 -#define CSAR_MASK (0x7f << CSAR_SHIFT) - -#define AC97_WRITE_RETRY 1 -#define AC97_READ_RETRY 5 - -/* manual-suggested AC97 codec access timeouts (us) */ -#define TMO_E1 500 /* 21 < E1 < 1000 */ -#define TMO_E2 13 /* 13 < E2 */ -#define TMO_E3 21 /* 21 < E3 */ -#define TMO_E4 500 /* 21 < E4 < 1000 */ - -struct hac_priv { - unsigned long mmio; /* HAC base address */ -} hac_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE240000, - }, - { - .mmio = 0xFE250000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE40000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -#define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg))) - -/* - * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906) - */ -static int hac_get_codec_data(struct hac_priv *hac, unsigned short r, - unsigned short *v) -{ - unsigned int to1, to2, i; - unsigned short adr; - - for (i = AC97_READ_RETRY; i; i--) { - *v = 0; - /* wait for HAC to receive something from the codec */ - for (to1 = TMO_E4; - to1 && !(HACREG(HACRSR) & RSR_STARY); - --to1) - udelay(1); - for (to2 = TMO_E4; - to2 && !(HACREG(HACRSR) & RSR_STDRY); - --to2) - udelay(1); - - if (!to1 && !to2) - return 0; /* codec comm is down */ - - adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT); - *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT); - - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - - if (r == adr) - break; - - /* manual says: wait at least 21 usec before retrying */ - udelay(21); - } - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - return i; -} - -static unsigned short hac_read_codec_aux(struct hac_priv *hac, - unsigned short reg) -{ - unsigned short val; - unsigned int i, to; - - for (i = AC97_READ_RETRY; i; i--) { - /* send_read_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDAMT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD; - local_irq_enable(); - - for (to = TMO_E3; - to && !(HACREG(HACTSR) & TSR_CMDAMT); - --to) - udelay(1); - - HACREG(HACTSR) &= ~TSR_CMDAMT; - val = 0; - if (hac_get_codec_data(hac, reg, &val) != 0) - break; - } - - return i ? val : ~0; -} - -static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int i, to; - /* write_codec_aux */ - for (i = AC97_WRITE_RETRY; i; i--) { - /* send_write_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT); - HACREG(HACCSDR) = (val << CSDR_SHIFT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD); - local_irq_enable(); - - /* poll-wait for CMDAMT and CMDDMT */ - for (to = TMO_E1; - to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT)); - --to) - udelay(1); - - HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT); - if (to) - break; - /* timeout, try again */ - } -} - -static unsigned short hac_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - return hac_read_codec_aux(hac, reg); -} - -static void hac_ac97_warmrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int tmo; - - HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9; - msleep(10); - HACREG(HACCR) = CR_ST | CR_B9; - for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--) - udelay(1); - - if (!tmo) - printk(KERN_INFO "hac: reset: AC97 link down!\n"); - /* settings this bit lets us have a conversation with codec */ - HACREG(HACACR) |= ACR_TX12ATOM; -} - -static void hac_ac97_coldrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac; - hac = &hac_cpu_data[unit_id]; - - HACREG(HACCR) = 0; - HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9; - msleep(10); - hac_ac97_warmrst(ac97); -} - -static struct snd_ac97_bus_ops hac_ac97_ops = { - .read = hac_ac97_read, - .write = hac_ac97_write, - .reset = hac_ac97_coldrst, - .warm_reset = hac_ac97_warmrst, -}; - -static int hac_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct hac_priv *hac = &hac_cpu_data[dai->id]; - int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; - - switch (params->msbits) { - case 16: - HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16; - HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20; - break; - case 20: - HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16; - HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20; - break; - default: - pr_debug("hac: invalid depth %d bit\n", params->msbits); - return -EINVAL; - break; - } - - return 0; -} - -#define AC97_RATES \ - SNDRV_PCM_RATE_8000_192000 - -#define AC97_FMTS \ - SNDRV_PCM_FMTBIT_S16_LE - -static const struct snd_soc_dai_ops hac_dai_ops = { - .hw_params = hac_hw_params, -}; - -static struct snd_soc_dai_driver sh4_hac_dai[] = { -{ - .name = "hac-dai.0", - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = &hac_dai_ops, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "hac-dai.1", - .id = 1, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = &hac_dai_ops, - -}, -#endif -}; - -static const struct snd_soc_component_driver sh4_hac_component = { - .name = "sh4-hac", - .legacy_dai_naming = 1, -}; - -static int hac_soc_platform_probe(struct platform_device *pdev) -{ - int ret; - - ret = snd_soc_set_ac97_ops(&hac_ac97_ops); - if (ret != 0) - return ret; - - return devm_snd_soc_register_component(&pdev->dev, &sh4_hac_component, - sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); -} - -static int hac_soc_platform_remove(struct platform_device *pdev) -{ - snd_soc_set_ac97_ops(NULL); - return 0; -} - -static struct platform_driver hac_pcm_driver = { - .driver = { - .name = "hac-pcm-audio", - }, - - .probe = hac_soc_platform_probe, - .remove = hac_soc_platform_remove, -}; - -module_platform_driver(hac_pcm_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c deleted file mode 100644 index 7082c12d3bf238..00000000000000 --- a/sound/soc/sh/migor.c +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// ALSA SoC driver for Migo-R -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski - -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include - -#include "../codecs/wm8978.h" -#include "siu.h" - -/* Default 8000Hz sampling frequency */ -static unsigned long codec_freq = 8000 * 512; - -static unsigned int use_count; - -/* External clock, sourced from the codec at the SIUMCKB pin */ -static unsigned long siumckb_recalc(struct clk *clk) -{ - return codec_freq; -} - -static struct sh_clk_ops siumckb_clk_ops = { - .recalc = siumckb_recalc, -}; - -static struct clk siumckb_clk = { - .ops = &siumckb_clk_ops, - .rate = 0, /* initialised at run-time */ -}; - -static struct clk_lookup *siumckb_lookup; - -static int migor_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - int ret; - unsigned int rate = params_rate(params); - - ret = snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 13000000, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKRATE, rate * 512); - if (ret < 0) - return ret; - - codec_freq = rate * 512; - /* - * This propagates the parent frequency change to children and - * recalculates the frequency table - */ - clk_set_rate(&siumckb_clk, codec_freq); - dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq); - - ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), SIU_CLKB_EXT, - codec_freq / 2, SND_SOC_CLOCK_IN); - - if (!ret) - use_count++; - - return ret; -} - -static int migor_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - - if (use_count) { - use_count--; - - if (!use_count) - snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 0, - SND_SOC_CLOCK_IN); - } else { - dev_dbg(codec_dai->dev, "Unbalanced hw_free!\n"); - } - - return 0; -} - -static const struct snd_soc_ops migor_dai_ops = { - .hw_params = migor_hw_params, - .hw_free = migor_hw_free, -}; - -static const struct snd_soc_dapm_widget migor_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone", NULL), - SND_SOC_DAPM_MIC("Onboard Microphone", NULL), - SND_SOC_DAPM_MIC("External Microphone", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* Headphone output connected to LHP/RHP, enable OUT4 for VMID */ - { "Headphone", NULL, "OUT4 VMID" }, - { "OUT4 VMID", NULL, "LHP" }, - { "OUT4 VMID", NULL, "RHP" }, - - /* On-board microphone */ - { "RMICN", NULL, "Mic Bias" }, - { "RMICP", NULL, "Mic Bias" }, - { "Mic Bias", NULL, "Onboard Microphone" }, - - /* External microphone */ - { "LMICN", NULL, "Mic Bias" }, - { "LMICP", NULL, "Mic Bias" }, - { "Mic Bias", NULL, "External Microphone" }, -}; - -/* migor digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(wm8978, - DAILINK_COMP_ARRAY(COMP_CPU("siu-pcm-audio")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8978.0-001a", "wm8978-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("siu-pcm-audio"))); - -static struct snd_soc_dai_link migor_dai = { - .name = "wm8978", - .stream_name = "WM8978", - .dai_fmt = SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &migor_dai_ops, - SND_SOC_DAILINK_REG(wm8978), -}; - -/* migor audio machine driver */ -static struct snd_soc_card snd_soc_migor = { - .name = "Migo-R", - .owner = THIS_MODULE, - .dai_link = &migor_dai, - .num_links = 1, - - .dapm_widgets = migor_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(migor_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static struct platform_device *migor_snd_device; - -static int __init migor_init(void) -{ - int ret; - - ret = clk_register(&siumckb_clk); - if (ret < 0) - return ret; - - siumckb_lookup = clkdev_create(&siumckb_clk, "siumckb_clk", NULL); - if (!siumckb_lookup) { - ret = -ENOMEM; - goto eclkdevalloc; - } - - /* Port number used on this machine: port B */ - migor_snd_device = platform_device_alloc("soc-audio", 1); - if (!migor_snd_device) { - ret = -ENOMEM; - goto epdevalloc; - } - - platform_set_drvdata(migor_snd_device, &snd_soc_migor); - - ret = platform_device_add(migor_snd_device); - if (ret) - goto epdevadd; - - return 0; - -epdevadd: - platform_device_put(migor_snd_device); -epdevalloc: - clkdev_drop(siumckb_lookup); -eclkdevalloc: - clk_unregister(&siumckb_clk); - return ret; -} - -static void __exit migor_exit(void) -{ - clkdev_drop(siumckb_lookup); - clk_unregister(&siumckb_clk); - platform_device_unregister(migor_snd_device); -} - -module_init(migor_init); -module_exit(migor_exit); - -MODULE_AUTHOR("Guennadi Liakhovetski "); -MODULE_DESCRIPTION("ALSA SoC Migor"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c deleted file mode 100644 index d267243a159ba6..00000000000000 --- a/sound/soc/sh/sh7760-ac97.c +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Generic AC97 sound support for SH7760 -// -// (c) 2007 Manuel Lauss - -#include -#include -#include -#include -#include -#include -#include - -#define IPSEL 0xFE400034 - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("hac-dai.0")), /* HAC0 */ - DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("sh7760-pcm-audio"))); - -static struct snd_soc_dai_link sh7760_ac97_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(ac97), -}; - -static struct snd_soc_card sh7760_ac97_soc_machine = { - .name = "SH7760 AC97", - .owner = THIS_MODULE, - .dai_link = &sh7760_ac97_dai, - .num_links = 1, -}; - -static struct platform_device *sh7760_ac97_snd_device; - -static int __init sh7760_ac97_init(void) -{ - int ret; - unsigned short ipsel; - - /* enable both AC97 controllers in pinmux reg */ - ipsel = __raw_readw(IPSEL); - __raw_writew(ipsel | (3 << 10), IPSEL); - - ret = -ENOMEM; - sh7760_ac97_snd_device = platform_device_alloc("soc-audio", -1); - if (!sh7760_ac97_snd_device) - goto out; - - platform_set_drvdata(sh7760_ac97_snd_device, - &sh7760_ac97_soc_machine); - ret = platform_device_add(sh7760_ac97_snd_device); - - if (ret) - platform_device_put(sh7760_ac97_snd_device); - -out: - return ret; -} - -static void __exit sh7760_ac97_exit(void) -{ - platform_device_unregister(sh7760_ac97_snd_device); -} - -module_init(sh7760_ac97_init); -module_exit(sh7760_ac97_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Generic SH7760 AC97 sound machine"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h deleted file mode 100644 index a675c36fc9d956..00000000000000 --- a/sound/soc/sh/siu.h +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// siu.h - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral. -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski -// Copyright (C) 2006 Carlos Munoz - -#ifndef SIU_H -#define SIU_H - -/* Common kernel and user-space firmware-building defines and types */ - -#define YRAM0_SIZE (0x0040 / 4) /* 16 */ -#define YRAM1_SIZE (0x0080 / 4) /* 32 */ -#define YRAM2_SIZE (0x0040 / 4) /* 16 */ -#define YRAM3_SIZE (0x0080 / 4) /* 32 */ -#define YRAM4_SIZE (0x0080 / 4) /* 32 */ -#define YRAM_DEF_SIZE (YRAM0_SIZE + YRAM1_SIZE + YRAM2_SIZE + \ - YRAM3_SIZE + YRAM4_SIZE) -#define YRAM_FIR_SIZE (0x0400 / 4) /* 256 */ -#define YRAM_IIR_SIZE (0x0200 / 4) /* 128 */ - -#define XRAM0_SIZE (0x0400 / 4) /* 256 */ -#define XRAM1_SIZE (0x0200 / 4) /* 128 */ -#define XRAM2_SIZE (0x0200 / 4) /* 128 */ - -/* PRAM program array size */ -#define PRAM0_SIZE (0x0100 / 4) /* 64 */ -#define PRAM1_SIZE ((0x2000 - 0x0100) / 4) /* 1984 */ - -#include - -struct siu_spb_param { - __u32 ab1a; /* input FIFO address */ - __u32 ab0a; /* output FIFO address */ - __u32 dir; /* 0=the ather except CPUOUTPUT, 1=CPUINPUT */ - __u32 event; /* SPB program starting conditions */ - __u32 stfifo; /* STFIFO register setting value */ - __u32 trdat; /* TRDAT register setting value */ -}; - -struct siu_firmware { - __u32 yram_fir_coeff[YRAM_FIR_SIZE]; - __u32 pram0[PRAM0_SIZE]; - __u32 pram1[PRAM1_SIZE]; - __u32 yram0[YRAM0_SIZE]; - __u32 yram1[YRAM1_SIZE]; - __u32 yram2[YRAM2_SIZE]; - __u32 yram3[YRAM3_SIZE]; - __u32 yram4[YRAM4_SIZE]; - __u32 spbpar_num; - struct siu_spb_param spbpar[32]; -}; - -#ifdef __KERNEL__ - -#include -#include -#include -#include - -#include -#include -#include - -#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */ -#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */ -#define SIU_PERIODS_MAX 64 /* Max periods in buffer */ -#define SIU_PERIODS_MIN 4 /* Min periods in buffer */ -#define SIU_BUFFER_BYTES_MAX (SIU_PERIOD_BYTES_MAX * SIU_PERIODS_MAX) - -/* SIU ports: only one can be used at a time */ -enum { - SIU_PORT_A, - SIU_PORT_B, - SIU_PORT_NUM, -}; - -/* SIU clock configuration */ -enum { - SIU_CLKA_PLL, - SIU_CLKA_EXT, - SIU_CLKB_PLL, - SIU_CLKB_EXT -}; - -struct device; -struct siu_info { - struct device *dev; - int port_id; - u32 __iomem *pram; - u32 __iomem *xram; - u32 __iomem *yram; - u32 __iomem *reg; - struct siu_firmware fw; -}; - -struct siu_stream { - struct work_struct work; - struct snd_pcm_substream *substream; - snd_pcm_format_t format; - size_t buf_bytes; - size_t period_bytes; - int cur_period; /* Period currently in dma */ - u32 volume; - snd_pcm_sframes_t xfer_cnt; /* Number of frames */ - u8 rw_flg; /* transfer status */ - /* DMA status */ - struct dma_chan *chan; /* DMA channel */ - struct dma_async_tx_descriptor *tx_desc; - dma_cookie_t cookie; - struct sh_dmae_slave param; -}; - -struct siu_port { - unsigned long play_cap; /* Used to track full duplex */ - struct snd_pcm *pcm; - struct siu_stream playback; - struct siu_stream capture; - u32 stfifo; /* STFIFO value from firmware */ - u32 trdat; /* TRDAT value from firmware */ -}; - -extern struct siu_port *siu_ports[SIU_PORT_NUM]; - -static inline struct siu_port *siu_port_info(struct snd_pcm_substream *substream) -{ - struct platform_device *pdev = - to_platform_device(substream->pcm->card->dev); - return siu_ports[pdev->id]; -} - -/* Register access */ -static inline void siu_write32(u32 __iomem *addr, u32 val) -{ - __raw_writel(val, addr); -} - -static inline u32 siu_read32(u32 __iomem *addr) -{ - return __raw_readl(addr); -} - -/* SIU registers */ -#define SIU_IFCTL (0x000 / sizeof(u32)) -#define SIU_SRCTL (0x004 / sizeof(u32)) -#define SIU_SFORM (0x008 / sizeof(u32)) -#define SIU_CKCTL (0x00c / sizeof(u32)) -#define SIU_TRDAT (0x010 / sizeof(u32)) -#define SIU_STFIFO (0x014 / sizeof(u32)) -#define SIU_DPAK (0x01c / sizeof(u32)) -#define SIU_CKREV (0x020 / sizeof(u32)) -#define SIU_EVNTC (0x028 / sizeof(u32)) -#define SIU_SBCTL (0x040 / sizeof(u32)) -#define SIU_SBPSET (0x044 / sizeof(u32)) -#define SIU_SBFSTS (0x068 / sizeof(u32)) -#define SIU_SBDVCA (0x06c / sizeof(u32)) -#define SIU_SBDVCB (0x070 / sizeof(u32)) -#define SIU_SBACTIV (0x074 / sizeof(u32)) -#define SIU_DMAIA (0x090 / sizeof(u32)) -#define SIU_DMAIB (0x094 / sizeof(u32)) -#define SIU_DMAOA (0x098 / sizeof(u32)) -#define SIU_DMAOB (0x09c / sizeof(u32)) -#define SIU_DMAML (0x0a0 / sizeof(u32)) -#define SIU_SPSTS (0x0cc / sizeof(u32)) -#define SIU_SPCTL (0x0d0 / sizeof(u32)) -#define SIU_BRGASEL (0x100 / sizeof(u32)) -#define SIU_BRRA (0x104 / sizeof(u32)) -#define SIU_BRGBSEL (0x108 / sizeof(u32)) -#define SIU_BRRB (0x10c / sizeof(u32)) - -extern const struct snd_soc_component_driver siu_component; -extern struct siu_info *siu_i2s_data; - -int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card); -void siu_free_port(struct siu_port *port_info); - -#endif - -#endif /* SIU_H */ diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c deleted file mode 100644 index f2a386fcd92e4d..00000000000000 --- a/sound/soc/sh/siu_dai.c +++ /dev/null @@ -1,799 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral. -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski -// Copyright (C) 2006 Carlos Munoz - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "siu.h" - -/* Board specifics */ -#if defined(CONFIG_CPU_SUBTYPE_SH7722) -# define SIU_MAX_VOLUME 0x1000 -#else -# define SIU_MAX_VOLUME 0x7fff -#endif - -#define PRAM_SIZE 0x2000 -#define XRAM_SIZE 0x800 -#define YRAM_SIZE 0x800 - -#define XRAM_OFFSET 0x4000 -#define YRAM_OFFSET 0x6000 -#define REG_OFFSET 0xc000 - -#define PLAYBACK_ENABLED 1 -#define CAPTURE_ENABLED 2 - -#define VOLUME_CAPTURE 0 -#define VOLUME_PLAYBACK 1 -#define DFLT_VOLUME_LEVEL 0x08000800 - -/* - * SPDIF is only available on port A and on some SIU implementations it is only - * available for input. Due to the lack of hardware to test it, SPDIF is left - * disabled in this driver version - */ -struct format_flag { - u32 i2s; - u32 pcm; - u32 spdif; - u32 mask; -}; - -struct port_flag { - struct format_flag playback; - struct format_flag capture; -}; - -struct siu_info *siu_i2s_data; - -static struct port_flag siu_flags[SIU_PORT_NUM] = { - [SIU_PORT_A] = { - .playback = { - .i2s = 0x50000000, - .pcm = 0x40000000, - .spdif = 0x80000000, /* not on all SIU versions */ - .mask = 0xd0000000, - }, - .capture = { - .i2s = 0x05000000, - .pcm = 0x04000000, - .spdif = 0x08000000, - .mask = 0x0d000000, - }, - }, - [SIU_PORT_B] = { - .playback = { - .i2s = 0x00500000, - .pcm = 0x00400000, - .spdif = 0, /* impossible - turn off */ - .mask = 0x00500000, - }, - .capture = { - .i2s = 0x00050000, - .pcm = 0x00040000, - .spdif = 0, /* impossible - turn off */ - .mask = 0x00050000, - }, - }, -}; - -static void siu_dai_start(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - - dev_dbg(port_info->pcm->card->dev, "%s\n", __func__); - - /* Issue software reset to siu */ - siu_write32(base + SIU_SRCTL, 0); - - /* Wait for the reset to take effect */ - udelay(1); - - port_info->stfifo = 0; - port_info->trdat = 0; - - /* portA, portB, SIU operate */ - siu_write32(base + SIU_SRCTL, 0x301); - - /* portA=256fs, portB=256fs */ - siu_write32(base + SIU_CKCTL, 0x40400000); - - /* portA's BRG does not divide SIUCKA */ - siu_write32(base + SIU_BRGASEL, 0); - siu_write32(base + SIU_BRRA, 0); - - /* portB's BRG divides SIUCKB by half */ - siu_write32(base + SIU_BRGBSEL, 1); - siu_write32(base + SIU_BRRB, 0); - - siu_write32(base + SIU_IFCTL, 0x44440000); - - /* portA: 32 bit/fs, master; portB: 32 bit/fs, master */ - siu_write32(base + SIU_SFORM, 0x0c0c0000); - - /* - * Volume levels: looks like the DSP firmware implements volume controls - * differently from what's described in the datasheet - */ - siu_write32(base + SIU_SBDVCA, port_info->playback.volume); - siu_write32(base + SIU_SBDVCB, port_info->capture.volume); -} - -static void siu_dai_stop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - - /* SIU software reset */ - siu_write32(base + SIU_SRCTL, 0); -} - -static void siu_dai_spbAselect(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - struct siu_firmware *fw = &info->fw; - u32 *ydef = fw->yram0; - u32 idx; - - /* path A use */ - if (!info->port_id) - idx = 1; /* portA */ - else - idx = 2; /* portB */ - - ydef[0] = (fw->spbpar[idx].ab1a << 16) | - (fw->spbpar[idx].ab0a << 8) | - (fw->spbpar[idx].dir << 7) | 3; - ydef[1] = fw->yram0[1]; /* 0x03000300 */ - ydef[2] = (16 / 2) << 24; - ydef[3] = fw->yram0[3]; /* 0 */ - ydef[4] = fw->yram0[4]; /* 0 */ - ydef[7] = fw->spbpar[idx].event; - port_info->stfifo |= fw->spbpar[idx].stfifo; - port_info->trdat |= fw->spbpar[idx].trdat; -} - -static void siu_dai_spbBselect(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - struct siu_firmware *fw = &info->fw; - u32 *ydef = fw->yram0; - u32 idx; - - /* path B use */ - if (!info->port_id) - idx = 7; /* portA */ - else - idx = 8; /* portB */ - - ydef[5] = (fw->spbpar[idx].ab1a << 16) | - (fw->spbpar[idx].ab0a << 8) | 1; - ydef[6] = fw->spbpar[idx].event; - port_info->stfifo |= fw->spbpar[idx].stfifo; - port_info->trdat |= fw->spbpar[idx].trdat; -} - -static void siu_dai_open(struct siu_stream *siu_stream) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - u32 srctl, ifctl; - - srctl = siu_read32(base + SIU_SRCTL); - ifctl = siu_read32(base + SIU_IFCTL); - - switch (info->port_id) { - case SIU_PORT_A: - /* portA operates */ - srctl |= 0x200; - ifctl &= ~0xc2; - break; - case SIU_PORT_B: - /* portB operates */ - srctl |= 0x100; - ifctl &= ~0x31; - break; - } - - siu_write32(base + SIU_SRCTL, srctl); - /* Unmute and configure portA */ - siu_write32(base + SIU_IFCTL, ifctl); -} - -/* - * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower - * packing is supported - */ -static void siu_dai_pcmdatapack(struct siu_stream *siu_stream) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - u32 dpak; - - dpak = siu_read32(base + SIU_DPAK); - - switch (info->port_id) { - case SIU_PORT_A: - dpak &= ~0xc0000000; - break; - case SIU_PORT_B: - dpak &= ~0x00c00000; - break; - } - - siu_write32(base + SIU_DPAK, dpak); -} - -static int siu_dai_spbstart(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_firmware *fw = &info->fw; - u32 *ydef = fw->yram0; - int cnt; - u32 __iomem *add; - u32 *ptr; - - /* Load SPB Program in PRAM */ - ptr = fw->pram0; - add = info->pram; - for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++) - siu_write32(add, *ptr); - - ptr = fw->pram1; - add = info->pram + (0x0100 / sizeof(u32)); - for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++) - siu_write32(add, *ptr); - - /* XRAM initialization */ - add = info->xram; - for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++) - siu_write32(add, 0); - - /* YRAM variable area initialization */ - add = info->yram; - for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++) - siu_write32(add, ydef[cnt]); - - /* YRAM FIR coefficient area initialization */ - add = info->yram + (0x0200 / sizeof(u32)); - for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++) - siu_write32(add, fw->yram_fir_coeff[cnt]); - - /* YRAM IIR coefficient area initialization */ - add = info->yram + (0x0600 / sizeof(u32)); - for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++) - siu_write32(add, 0); - - siu_write32(base + SIU_TRDAT, port_info->trdat); - port_info->trdat = 0x0; - - - /* SPB start condition: software */ - siu_write32(base + SIU_SBACTIV, 0); - /* Start SPB */ - siu_write32(base + SIU_SBCTL, 0xc0000000); - /* Wait for program to halt */ - cnt = 0x10000; - while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000) - cpu_relax(); - - if (!cnt) - return -EBUSY; - - /* SPB program start address setting */ - siu_write32(base + SIU_SBPSET, 0x00400000); - /* SPB hardware start(FIFOCTL source) */ - siu_write32(base + SIU_SBACTIV, 0xc0000000); - - return 0; -} - -static void siu_dai_spbstop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - - siu_write32(base + SIU_SBACTIV, 0); - /* SPB stop */ - siu_write32(base + SIU_SBCTL, 0); - - port_info->stfifo = 0; -} - -/* API functions */ - -/* Playback and capture hardware properties are identical */ -static const struct snd_pcm_hardware siu_dai_pcm_hw = { - .info = SNDRV_PCM_INFO_INTERLEAVED, - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = SIU_BUFFER_BYTES_MAX, - .period_bytes_min = SIU_PERIOD_BYTES_MIN, - .period_bytes_max = SIU_PERIOD_BYTES_MAX, - .periods_min = SIU_PERIODS_MIN, - .periods_max = SIU_PERIODS_MAX, -}; - -static int siu_dai_info_volume(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_info *uinfo) -{ - struct siu_port *port_info = snd_kcontrol_chip(kctrl); - - dev_dbg(port_info->pcm->card->dev, "%s\n", __func__); - - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = SIU_MAX_VOLUME; - - return 0; -} - -static int siu_dai_get_volume(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_value *ucontrol) -{ - struct siu_port *port_info = snd_kcontrol_chip(kctrl); - struct device *dev = port_info->pcm->card->dev; - u32 vol; - - dev_dbg(dev, "%s\n", __func__); - - switch (kctrl->private_value) { - case VOLUME_PLAYBACK: - /* Playback is always on port 0 */ - vol = port_info->playback.volume; - ucontrol->value.integer.value[0] = vol & 0xffff; - ucontrol->value.integer.value[1] = vol >> 16 & 0xffff; - break; - case VOLUME_CAPTURE: - /* Capture is always on port 1 */ - vol = port_info->capture.volume; - ucontrol->value.integer.value[0] = vol & 0xffff; - ucontrol->value.integer.value[1] = vol >> 16 & 0xffff; - break; - default: - dev_err(dev, "%s() invalid private_value=%ld\n", - __func__, kctrl->private_value); - return -EINVAL; - } - - return 0; -} - -static int siu_dai_put_volume(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_value *ucontrol) -{ - struct siu_port *port_info = snd_kcontrol_chip(kctrl); - struct device *dev = port_info->pcm->card->dev; - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - u32 new_vol; - u32 cur_vol; - - dev_dbg(dev, "%s\n", __func__); - - if (ucontrol->value.integer.value[0] < 0 || - ucontrol->value.integer.value[0] > SIU_MAX_VOLUME || - ucontrol->value.integer.value[1] < 0 || - ucontrol->value.integer.value[1] > SIU_MAX_VOLUME) - return -EINVAL; - - new_vol = ucontrol->value.integer.value[0] | - ucontrol->value.integer.value[1] << 16; - - /* See comment above - DSP firmware implementation */ - switch (kctrl->private_value) { - case VOLUME_PLAYBACK: - /* Playback is always on port 0 */ - cur_vol = port_info->playback.volume; - siu_write32(base + SIU_SBDVCA, new_vol); - port_info->playback.volume = new_vol; - break; - case VOLUME_CAPTURE: - /* Capture is always on port 1 */ - cur_vol = port_info->capture.volume; - siu_write32(base + SIU_SBDVCB, new_vol); - port_info->capture.volume = new_vol; - break; - default: - dev_err(dev, "%s() invalid private_value=%ld\n", - __func__, kctrl->private_value); - return -EINVAL; - } - - if (cur_vol != new_vol) - return 1; - - return 0; -} - -static const struct snd_kcontrol_new playback_controls = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .index = 0, - .info = siu_dai_info_volume, - .get = siu_dai_get_volume, - .put = siu_dai_put_volume, - .private_value = VOLUME_PLAYBACK, -}; - -static const struct snd_kcontrol_new capture_controls = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Capture Volume", - .index = 0, - .info = siu_dai_info_volume, - .get = siu_dai_get_volume, - .put = siu_dai_put_volume, - .private_value = VOLUME_CAPTURE, -}; - -int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card) -{ - struct device *dev = card->dev; - struct snd_kcontrol *kctrl; - int ret; - - *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL); - if (!*port_info) - return -ENOMEM; - - dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info); - - (*port_info)->playback.volume = DFLT_VOLUME_LEVEL; - (*port_info)->capture.volume = DFLT_VOLUME_LEVEL; - - /* - * Add mixer support. The SPB is used to change the volume. Both - * ports use the same SPB. Therefore, we only register one - * control instance since it will be used by both channels. - * In error case we continue without controls. - */ - kctrl = snd_ctl_new1(&playback_controls, *port_info); - ret = snd_ctl_add(card, kctrl); - if (ret < 0) - dev_err(dev, - "failed to add playback controls %p port=%d err=%d\n", - kctrl, port, ret); - - kctrl = snd_ctl_new1(&capture_controls, *port_info); - ret = snd_ctl_add(card, kctrl); - if (ret < 0) - dev_err(dev, - "failed to add capture controls %p port=%d err=%d\n", - kctrl, port, ret); - - return 0; -} - -void siu_free_port(struct siu_port *port_info) -{ - kfree(port_info); -} - -static int siu_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - struct snd_pcm_runtime *rt = substream->runtime; - struct siu_port *port_info = siu_port_info(substream); - int ret; - - dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__, - info->port_id, port_info); - - snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw); - - ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS); - if (unlikely(ret < 0)) - return ret; - - siu_dai_start(port_info); - - return 0; -} - -static void siu_dai_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - struct siu_port *port_info = siu_port_info(substream); - - dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__, - info->port_id, port_info); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - port_info->play_cap &= ~PLAYBACK_ENABLED; - else - port_info->play_cap &= ~CAPTURE_ENABLED; - - /* Stop the siu if the other stream is not using it */ - if (!port_info->play_cap) { - /* during stmread or stmwrite ? */ - if (WARN_ON(port_info->playback.rw_flg || port_info->capture.rw_flg)) - return; - siu_dai_spbstop(port_info); - siu_dai_stop(port_info); - } -} - -/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */ -static int siu_dai_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - struct snd_pcm_runtime *rt = substream->runtime; - struct siu_port *port_info = siu_port_info(substream); - struct siu_stream *siu_stream; - int self, ret; - - dev_dbg(substream->pcm->card->dev, - "%s: port %d, active streams %lx, %d channels\n", - __func__, info->port_id, port_info->play_cap, rt->channels); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - self = PLAYBACK_ENABLED; - siu_stream = &port_info->playback; - } else { - self = CAPTURE_ENABLED; - siu_stream = &port_info->capture; - } - - /* Set up the siu if not already done */ - if (!port_info->play_cap) { - siu_stream->rw_flg = 0; /* stream-data transfer flag */ - - siu_dai_spbAselect(port_info); - siu_dai_spbBselect(port_info); - - siu_dai_open(siu_stream); - - siu_dai_pcmdatapack(siu_stream); - - ret = siu_dai_spbstart(port_info); - if (ret < 0) - goto fail; - } else { - ret = 0; - } - - port_info->play_cap |= self; - -fail: - return ret; -} - -/* - * SIU can set bus format to I2S / PCM / SPDIF independently for playback and - * capture, however, the current API sets the bus format globally for a DAI. - */ -static int siu_dai_set_fmt(struct snd_soc_dai *dai, - unsigned int fmt) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - u32 __iomem *base = info->reg; - u32 ifctl; - - dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n", - __func__, fmt, info->port_id); - - if (info->port_id < 0) - return -ENODEV; - - /* Here select between I2S / PCM / SPDIF */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - ifctl = siu_flags[info->port_id].playback.i2s | - siu_flags[info->port_id].capture.i2s; - break; - case SND_SOC_DAIFMT_LEFT_J: - ifctl = siu_flags[info->port_id].playback.pcm | - siu_flags[info->port_id].capture.pcm; - break; - /* SPDIF disabled - see comment at the top */ - default: - return -EINVAL; - } - - ifctl |= ~(siu_flags[info->port_id].playback.mask | - siu_flags[info->port_id].capture.mask) & - siu_read32(base + SIU_IFCTL); - siu_write32(base + SIU_IFCTL, ifctl); - - return 0; -} - -static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, - unsigned int freq, int dir) -{ - struct clk *siu_clk, *parent_clk; - char *siu_name, *parent_name; - int ret; - - if (dir != SND_SOC_CLOCK_IN) - return -EINVAL; - - dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id); - - switch (clk_id) { - case SIU_CLKA_PLL: - siu_name = "siua_clk"; - parent_name = "pll_clk"; - break; - case SIU_CLKA_EXT: - siu_name = "siua_clk"; - parent_name = "siumcka_clk"; - break; - case SIU_CLKB_PLL: - siu_name = "siub_clk"; - parent_name = "pll_clk"; - break; - case SIU_CLKB_EXT: - siu_name = "siub_clk"; - parent_name = "siumckb_clk"; - break; - default: - return -EINVAL; - } - - siu_clk = clk_get(dai->dev, siu_name); - if (IS_ERR(siu_clk)) { - dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__, - PTR_ERR(siu_clk)); - return PTR_ERR(siu_clk); - } - - parent_clk = clk_get(dai->dev, parent_name); - if (IS_ERR(parent_clk)) { - ret = PTR_ERR(parent_clk); - dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret); - goto epclkget; - } - - ret = clk_set_parent(siu_clk, parent_clk); - if (ret < 0) { - dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret); - goto eclksetp; - } - - ret = clk_set_rate(siu_clk, freq); - if (ret < 0) - dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret); - - /* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */ -eclksetp: - clk_put(parent_clk); -epclkget: - clk_put(siu_clk); - - return ret; -} - -static const struct snd_soc_dai_ops siu_dai_ops = { - .startup = siu_dai_startup, - .shutdown = siu_dai_shutdown, - .prepare = siu_dai_prepare, - .set_sysclk = siu_dai_set_sysclk, - .set_fmt = siu_dai_set_fmt, -}; - -static struct snd_soc_dai_driver siu_i2s_dai = { - .name = "siu-i2s-dai", - .playback = { - .channels_min = 2, - .channels_max = 2, - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_8000_48000, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_8000_48000, - }, - .ops = &siu_dai_ops, -}; - -static int siu_probe(struct platform_device *pdev) -{ - const struct firmware *fw_entry; - struct resource *res, *region; - struct siu_info *info; - int ret; - - info = devm_kmalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - siu_i2s_data = info; - info->dev = &pdev->dev; - - ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev); - if (ret) - return ret; - - /* - * Loaded firmware is "const" - read only, but we have to modify it in - * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect() - */ - memcpy(&info->fw, fw_entry->data, fw_entry->size); - - release_firmware(fw_entry); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - region = devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), pdev->name); - if (!region) { - dev_err(&pdev->dev, "SIU region already claimed\n"); - return -EBUSY; - } - - info->pram = devm_ioremap(&pdev->dev, res->start, PRAM_SIZE); - if (!info->pram) - return -ENOMEM; - info->xram = devm_ioremap(&pdev->dev, res->start + XRAM_OFFSET, - XRAM_SIZE); - if (!info->xram) - return -ENOMEM; - info->yram = devm_ioremap(&pdev->dev, res->start + YRAM_OFFSET, - YRAM_SIZE); - if (!info->yram) - return -ENOMEM; - info->reg = devm_ioremap(&pdev->dev, res->start + REG_OFFSET, - resource_size(res) - REG_OFFSET); - if (!info->reg) - return -ENOMEM; - - dev_set_drvdata(&pdev->dev, info); - - /* register using ARRAY version so we can keep dai name */ - ret = devm_snd_soc_register_component(&pdev->dev, &siu_component, - &siu_i2s_dai, 1); - if (ret < 0) - return ret; - - pm_runtime_enable(&pdev->dev); - - return 0; -} - -static int siu_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - return 0; -} - -static struct platform_driver siu_driver = { - .driver = { - .name = "siu-pcm-audio", - }, - .probe = siu_probe, - .remove = siu_remove, -}; - -module_platform_driver(siu_driver); - -MODULE_AUTHOR("Carlos Munoz "); -MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c deleted file mode 100644 index f15ff36e793455..00000000000000 --- a/sound/soc/sh/siu_pcm.c +++ /dev/null @@ -1,553 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// siu_pcm.c - ALSA driver for Renesas SH7343, SH7722 SIU peripheral. -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski -// Copyright (C) 2006 Carlos Munoz - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "siu.h" - -#define DRV_NAME "siu-i2s" -#define GET_MAX_PERIODS(buf_bytes, period_bytes) \ - ((buf_bytes) / (period_bytes)) -#define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \ - ((buf_addr) + ((period_num) * (period_bytes))) - -#define RWF_STM_RD 0x01 /* Read in progress */ -#define RWF_STM_WT 0x02 /* Write in progress */ - -struct siu_port *siu_ports[SIU_PORT_NUM]; - -/* transfersize is number of u32 dma transfers per period */ -static int siu_pcm_stmwrite_stop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->playback; - u32 stfifo; - - if (!siu_stream->rw_flg) - return -EPERM; - - /* output FIFO disable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, stfifo & ~0x0c180c18); - pr_debug("%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo & ~0x0c180c18); - - /* during stmwrite clear */ - siu_stream->rw_flg = 0; - - return 0; -} - -static int siu_pcm_stmwrite_start(struct siu_port *port_info) -{ - struct siu_stream *siu_stream = &port_info->playback; - - if (siu_stream->rw_flg) - return -EPERM; - - /* Current period in buffer */ - port_info->playback.cur_period = 0; - - /* during stmwrite flag set */ - siu_stream->rw_flg = RWF_STM_WT; - - /* DMA transfer start */ - queue_work(system_highpri_wq, &siu_stream->work); - - return 0; -} - -static void siu_dma_tx_complete(void *arg) -{ - struct siu_stream *siu_stream = arg; - - if (!siu_stream->rw_flg) - return; - - /* Update completed period count */ - if (++siu_stream->cur_period >= - GET_MAX_PERIODS(siu_stream->buf_bytes, - siu_stream->period_bytes)) - siu_stream->cur_period = 0; - - pr_debug("%s: done period #%d (%u/%u bytes), cookie %d\n", - __func__, siu_stream->cur_period, - siu_stream->cur_period * siu_stream->period_bytes, - siu_stream->buf_bytes, siu_stream->cookie); - - queue_work(system_highpri_wq, &siu_stream->work); - - /* Notify alsa: a period is done */ - snd_pcm_period_elapsed(siu_stream->substream); -} - -static int siu_pcm_wr_set(struct siu_port *port_info, - dma_addr_t buff, u32 size) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->playback; - struct snd_pcm_substream *substream = siu_stream->substream; - struct device *dev = substream->pcm->card->dev; - struct dma_async_tx_descriptor *desc; - dma_cookie_t cookie; - struct scatterlist sg; - u32 stfifo; - - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)), - size, offset_in_page(buff)); - sg_dma_len(&sg) = size; - sg_dma_address(&sg) = buff; - - desc = dmaengine_prep_slave_sg(siu_stream->chan, - &sg, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(dev, "Failed to allocate a dma descriptor\n"); - return -ENOMEM; - } - - desc->callback = siu_dma_tx_complete; - desc->callback_param = siu_stream; - cookie = dmaengine_submit(desc); - if (cookie < 0) { - dev_err(dev, "Failed to submit a dma transfer\n"); - return cookie; - } - - siu_stream->tx_desc = desc; - siu_stream->cookie = cookie; - - dma_async_issue_pending(siu_stream->chan); - - /* only output FIFO enable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, stfifo | (port_info->stfifo & 0x0c180c18)); - dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo | (port_info->stfifo & 0x0c180c18)); - - return 0; -} - -static int siu_pcm_rd_set(struct siu_port *port_info, - dma_addr_t buff, size_t size) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->capture; - struct snd_pcm_substream *substream = siu_stream->substream; - struct device *dev = substream->pcm->card->dev; - struct dma_async_tx_descriptor *desc; - dma_cookie_t cookie; - struct scatterlist sg; - u32 stfifo; - - dev_dbg(dev, "%s: %u@%llx\n", __func__, size, (unsigned long long)buff); - - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)), - size, offset_in_page(buff)); - sg_dma_len(&sg) = size; - sg_dma_address(&sg) = buff; - - desc = dmaengine_prep_slave_sg(siu_stream->chan, - &sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(dev, "Failed to allocate dma descriptor\n"); - return -ENOMEM; - } - - desc->callback = siu_dma_tx_complete; - desc->callback_param = siu_stream; - cookie = dmaengine_submit(desc); - if (cookie < 0) { - dev_err(dev, "Failed to submit dma descriptor\n"); - return cookie; - } - - siu_stream->tx_desc = desc; - siu_stream->cookie = cookie; - - dma_async_issue_pending(siu_stream->chan); - - /* only input FIFO enable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, siu_read32(base + SIU_STFIFO) | - (port_info->stfifo & 0x13071307)); - dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo | (port_info->stfifo & 0x13071307)); - - return 0; -} - -static void siu_io_work(struct work_struct *work) -{ - struct siu_stream *siu_stream = container_of(work, struct siu_stream, - work); - struct snd_pcm_substream *substream = siu_stream->substream; - struct device *dev = substream->pcm->card->dev; - struct snd_pcm_runtime *rt = substream->runtime; - struct siu_port *port_info = siu_port_info(substream); - - dev_dbg(dev, "%s: flags %x\n", __func__, siu_stream->rw_flg); - - if (!siu_stream->rw_flg) { - dev_dbg(dev, "%s: stream inactive\n", __func__); - return; - } - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - dma_addr_t buff; - size_t count; - - buff = (dma_addr_t)PERIOD_OFFSET(rt->dma_addr, - siu_stream->cur_period, - siu_stream->period_bytes); - count = siu_stream->period_bytes; - - /* DMA transfer start */ - siu_pcm_rd_set(port_info, buff, count); - } else { - siu_pcm_wr_set(port_info, - (dma_addr_t)PERIOD_OFFSET(rt->dma_addr, - siu_stream->cur_period, - siu_stream->period_bytes), - siu_stream->period_bytes); - } -} - -/* Capture */ -static int siu_pcm_stmread_start(struct siu_port *port_info) -{ - struct siu_stream *siu_stream = &port_info->capture; - - if (siu_stream->xfer_cnt > 0x1000000) - return -EINVAL; - if (siu_stream->rw_flg) - return -EPERM; - - /* Current period in buffer */ - siu_stream->cur_period = 0; - - /* during stmread flag set */ - siu_stream->rw_flg = RWF_STM_RD; - - queue_work(system_highpri_wq, &siu_stream->work); - - return 0; -} - -static int siu_pcm_stmread_stop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->capture; - struct device *dev = siu_stream->substream->pcm->card->dev; - u32 stfifo; - - if (!siu_stream->rw_flg) - return -EPERM; - - /* input FIFO disable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, stfifo & ~0x13071307); - dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo & ~0x13071307); - - /* during stmread flag clear */ - siu_stream->rw_flg = 0; - - return 0; -} - -static bool filter(struct dma_chan *chan, void *secondary) -{ - struct sh_dmae_slave *param = secondary; - - pr_debug("%s: secondary ID %d\n", __func__, param->shdma_slave.slave_id); - - chan->private = ¶m->shdma_slave; - return true; -} - -static int siu_pcm_open(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - /* Playback / Capture */ - struct siu_platform *pdata = component->dev->platform_data; - struct siu_info *info = siu_i2s_data; - struct siu_port *port_info = siu_port_info(ss); - struct siu_stream *siu_stream; - u32 port = info->port_id; - struct device *dev = ss->pcm->card->dev; - dma_cap_mask_t mask; - struct sh_dmae_slave *param; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - dev_dbg(dev, "%s, port=%d@%p\n", __func__, port, port_info); - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) { - siu_stream = &port_info->playback; - param = &siu_stream->param; - param->shdma_slave.slave_id = port ? pdata->dma_slave_tx_b : - pdata->dma_slave_tx_a; - } else { - siu_stream = &port_info->capture; - param = &siu_stream->param; - param->shdma_slave.slave_id = port ? pdata->dma_slave_rx_b : - pdata->dma_slave_rx_a; - } - - /* Get DMA channel */ - siu_stream->chan = dma_request_channel(mask, filter, param); - if (!siu_stream->chan) { - dev_err(dev, "DMA channel allocation failed!\n"); - return -EBUSY; - } - - siu_stream->substream = ss; - - return 0; -} - -static int siu_pcm_close(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - struct siu_info *info = siu_i2s_data; - struct device *dev = ss->pcm->card->dev; - struct siu_port *port_info = siu_port_info(ss); - struct siu_stream *siu_stream; - - dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id); - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_stream = &port_info->playback; - else - siu_stream = &port_info->capture; - - dma_release_channel(siu_stream->chan); - siu_stream->chan = NULL; - - siu_stream->substream = NULL; - - return 0; -} - -static int siu_pcm_prepare(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - struct siu_info *info = siu_i2s_data; - struct siu_port *port_info = siu_port_info(ss); - struct device *dev = ss->pcm->card->dev; - struct snd_pcm_runtime *rt; - struct siu_stream *siu_stream; - snd_pcm_sframes_t xfer_cnt; - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_stream = &port_info->playback; - else - siu_stream = &port_info->capture; - - rt = siu_stream->substream->runtime; - - siu_stream->buf_bytes = snd_pcm_lib_buffer_bytes(ss); - siu_stream->period_bytes = snd_pcm_lib_period_bytes(ss); - - dev_dbg(dev, "%s: port=%d, %d channels, period=%u bytes\n", __func__, - info->port_id, rt->channels, siu_stream->period_bytes); - - /* We only support buffers that are multiples of the period */ - if (siu_stream->buf_bytes % siu_stream->period_bytes) { - dev_err(dev, "%s() - buffer=%d not multiple of period=%d\n", - __func__, siu_stream->buf_bytes, - siu_stream->period_bytes); - return -EINVAL; - } - - xfer_cnt = bytes_to_frames(rt, siu_stream->period_bytes); - if (!xfer_cnt || xfer_cnt > 0x1000000) - return -EINVAL; - - siu_stream->format = rt->format; - siu_stream->xfer_cnt = xfer_cnt; - - dev_dbg(dev, "port=%d buf=%lx buf_bytes=%d period_bytes=%d " - "format=%d channels=%d xfer_cnt=%d\n", info->port_id, - (unsigned long)rt->dma_addr, siu_stream->buf_bytes, - siu_stream->period_bytes, - siu_stream->format, rt->channels, (int)xfer_cnt); - - return 0; -} - -static int siu_pcm_trigger(struct snd_soc_component *component, - struct snd_pcm_substream *ss, int cmd) -{ - struct siu_info *info = siu_i2s_data; - struct device *dev = ss->pcm->card->dev; - struct siu_port *port_info = siu_port_info(ss); - int ret; - - dev_dbg(dev, "%s: port=%d@%p, cmd=%d\n", __func__, - info->port_id, port_info, cmd); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = siu_pcm_stmwrite_start(port_info); - else - ret = siu_pcm_stmread_start(port_info); - - if (ret < 0) - dev_warn(dev, "%s: start failed on port=%d\n", - __func__, info->port_id); - - break; - case SNDRV_PCM_TRIGGER_STOP: - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_pcm_stmwrite_stop(port_info); - else - siu_pcm_stmread_stop(port_info); - ret = 0; - - break; - default: - dev_err(dev, "%s() unsupported cmd=%d\n", __func__, cmd); - ret = -EINVAL; - } - - return ret; -} - -/* - * So far only resolution of one period is supported, subject to extending the - * dmangine API - */ -static snd_pcm_uframes_t -siu_pcm_pointer_dma(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - struct device *dev = ss->pcm->card->dev; - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_port *port_info = siu_port_info(ss); - struct snd_pcm_runtime *rt = ss->runtime; - size_t ptr; - struct siu_stream *siu_stream; - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_stream = &port_info->playback; - else - siu_stream = &port_info->capture; - - /* - * ptr is the offset into the buffer where the dma is currently at. We - * check if the dma buffer has just wrapped. - */ - ptr = PERIOD_OFFSET(rt->dma_addr, - siu_stream->cur_period, - siu_stream->period_bytes) - rt->dma_addr; - - dev_dbg(dev, - "%s: port=%d, events %x, FSTS %x, xferred %u/%u, cookie %d\n", - __func__, info->port_id, siu_read32(base + SIU_EVNTC), - siu_read32(base + SIU_SBFSTS), ptr, siu_stream->buf_bytes, - siu_stream->cookie); - - if (ptr >= siu_stream->buf_bytes) - ptr = 0; - - return bytes_to_frames(ss->runtime, ptr); -} - -static int siu_pcm_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) -{ - /* card->dev == socdev->dev, see snd_soc_new_pcms() */ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - struct siu_info *info = siu_i2s_data; - struct platform_device *pdev = to_platform_device(card->dev); - int ret; - int i; - - /* pdev->id selects between SIUA and SIUB */ - if (pdev->id < 0 || pdev->id >= SIU_PORT_NUM) - return -EINVAL; - - info->port_id = pdev->id; - - /* - * While the siu has 2 ports, only one port can be on at a time (only 1 - * SPB). So far all the boards using the siu had only one of the ports - * wired to a codec. To simplify things, we only register one port with - * alsa. In case both ports are needed, it should be changed here - */ - for (i = pdev->id; i < pdev->id + 1; i++) { - struct siu_port **port_info = &siu_ports[i]; - - ret = siu_init_port(i, port_info, card); - if (ret < 0) - return ret; - - snd_pcm_set_managed_buffer_all(pcm, - SNDRV_DMA_TYPE_DEV, card->dev, - SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX); - - (*port_info)->pcm = pcm; - - /* IO works */ - INIT_WORK(&(*port_info)->playback.work, siu_io_work); - INIT_WORK(&(*port_info)->capture.work, siu_io_work); - } - - dev_info(card->dev, "SuperH SIU driver initialized.\n"); - return 0; -} - -static void siu_pcm_free(struct snd_soc_component *component, - struct snd_pcm *pcm) -{ - struct platform_device *pdev = to_platform_device(pcm->card->dev); - struct siu_port *port_info = siu_ports[pdev->id]; - - cancel_work_sync(&port_info->capture.work); - cancel_work_sync(&port_info->playback.work); - - siu_free_port(port_info); - - dev_dbg(pcm->card->dev, "%s\n", __func__); -} - -const struct snd_soc_component_driver siu_component = { - .name = DRV_NAME, - .open = siu_pcm_open, - .close = siu_pcm_close, - .prepare = siu_pcm_prepare, - .trigger = siu_pcm_trigger, - .pointer = siu_pcm_pointer_dma, - .pcm_construct = siu_pcm_new, - .pcm_destruct = siu_pcm_free, - .legacy_dai_naming = 1, -}; -EXPORT_SYMBOL_GPL(siu_component); diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c deleted file mode 100644 index 96cf523c227343..00000000000000 --- a/sound/soc/sh/ssi.c +++ /dev/null @@ -1,403 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Serial Sound Interface (I2S) support for SH7760/SH7780 -// -// Copyright (c) 2007 Manuel Lauss -// -// dont forget to set IPSEL/OMSEL register bits (in your board code) to -// enable SSI output pins! - -/* - * LIMITATIONS: - * The SSI unit has only one physical data line, so full duplex is - * impossible. This can be remedied on the SH7760 by using the - * other SSI unit for recording; however the SH7780 has only 1 SSI - * unit, and its pins are shared with the AC97 unit, among others. - * - * FEATURES: - * The SSI features "compressed mode": in this mode it continuously - * streams PCM data over the I2S lines and uses LRCK as a handshake - * signal. Can be used to send compressed data (AC3/DTS) to a DSP. - * The number of bits sent over the wire in a frame can be adjusted - * and can be independent from the actual sample bit depth. This is - * useful to support TDM mode codecs like the AD1939 which have a - * fixed TDM slot size, regardless of sample resolution. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define SSICR 0x00 -#define SSISR 0x04 - -#define CR_DMAEN (1 << 28) -#define CR_CHNL_SHIFT 22 -#define CR_CHNL_MASK (3 << CR_CHNL_SHIFT) -#define CR_DWL_SHIFT 19 -#define CR_DWL_MASK (7 << CR_DWL_SHIFT) -#define CR_SWL_SHIFT 16 -#define CR_SWL_MASK (7 << CR_SWL_SHIFT) -#define CR_SCK_MASTER (1 << 15) /* bitclock master bit */ -#define CR_SWS_MASTER (1 << 14) /* wordselect master bit */ -#define CR_SCKP (1 << 13) /* I2Sclock polarity */ -#define CR_SWSP (1 << 12) /* LRCK polarity */ -#define CR_SPDP (1 << 11) -#define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */ -#define CR_PDTA (1 << 9) /* fifo data alignment */ -#define CR_DEL (1 << 8) /* delay data by 1 i2sclk */ -#define CR_BREN (1 << 7) /* clock gating in burst mode */ -#define CR_CKDIV_SHIFT 4 -#define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */ -#define CR_MUTE (1 << 3) /* SSI mute */ -#define CR_CPEN (1 << 2) /* compressed mode */ -#define CR_TRMD (1 << 1) /* transmit/receive select */ -#define CR_EN (1 << 0) /* enable SSI */ - -#define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg))) - -struct ssi_priv { - unsigned long mmio; - unsigned long sysclk; - int inuse; -} ssi_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE680000, - }, - { - .mmio = 0xFE690000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE70000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -/* - * track usage of the SSI; it is simplex-only so prevent attempts of - * concurrent playback + capture. FIXME: any locking required? - */ -static int ssi_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - if (ssi->inuse) { - pr_debug("ssi: already in use!\n"); - return -EBUSY; - } else - ssi->inuse = 1; - return 0; -} - -static void ssi_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - - ssi->inuse = 0; -} - -static int ssi_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - SSIREG(SSICR) |= CR_DMAEN | CR_EN; - break; - case SNDRV_PCM_TRIGGER_STOP: - SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int ssi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr = SSIREG(SSICR); - unsigned int bits, channels, swl, recv, i; - - channels = params_channels(params); - bits = params->msbits; - recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; - - pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr); - pr_debug("bits: %u channels: %u\n", bits, channels); - - ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA | - CR_SWL_MASK); - - /* direction (send/receive) */ - if (!recv) - ssicr |= CR_TRMD; /* transmit */ - - /* channels */ - if ((channels < 2) || (channels > 8) || (channels & 1)) { - pr_debug("ssi: invalid number of channels\n"); - return -EINVAL; - } - ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT; - - /* DATA WORD LENGTH (DWL): databits in audio sample */ - i = 0; - switch (bits) { - case 32: ++i; - case 24: ++i; - case 22: ++i; - case 20: ++i; - case 18: ++i; - case 16: ++i; - ssicr |= i << CR_DWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid sample width\n"); - return -EINVAL; - } - - /* - * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S - * wires. This is usually bits_per_sample x channels/2; i.e. in - * Stereo mode the SWL equals DWL. SWL can be bigger than the - * product of (channels_per_slot x samplebits), e.g. for codecs - * like the AD1939 which only accept 32bit wide TDM slots. For - * "standard" I2S operation we set SWL = chans / 2 * DWL here. - * Waiting for ASoC to get TDM support ;-) - */ - if ((bits > 16) && (bits <= 24)) { - bits = 24; /* these are padded by the SSI */ - /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */ - } - i = 0; - swl = (bits * channels) / 2; - switch (swl) { - case 256: ++i; - case 128: ++i; - case 64: ++i; - case 48: ++i; - case 32: ++i; - case 16: ++i; - ssicr |= i << CR_SWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid system word length computed\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - - pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr); - return 0; -} - -static int ssi_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, - unsigned int freq, int dir) -{ - struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id]; - - ssi->sysclk = freq; - - return 0; -} - -/* - * This divider is used to generate the SSI_SCK (I2S bitclock) from the - * clock at the HAC_BIT_CLK ("oversampling clock") pin. - */ -static int ssi_set_clkdiv(struct snd_soc_dai *dai, int did, int div) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr; - int i; - - i = 0; - ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK; - switch (div) { - case 16: ++i; - case 8: ++i; - case 4: ++i; - case 2: ++i; - SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT); - case 1: break; - default: - pr_debug("ssi: invalid sck divider %d\n", div); - return -EINVAL; - } - - return 0; -} - -static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr = SSIREG(SSICR); - - pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr); - - ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP | - CR_SWS_MASTER | CR_SCK_MASTER); - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - break; - case SND_SOC_DAIFMT_RIGHT_J: - ssicr |= CR_DEL | CR_PDTA; - break; - case SND_SOC_DAIFMT_LEFT_J: - ssicr |= CR_DEL; - break; - default: - pr_debug("ssi: unsupported format\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { - case SND_SOC_DAIFMT_CONT: - break; - case SND_SOC_DAIFMT_GATED: - ssicr |= CR_BREN; - break; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - ssicr |= CR_SCKP; /* sample data at low clkedge */ - break; - case SND_SOC_DAIFMT_NB_IF: - ssicr |= CR_SCKP | CR_SWSP; - break; - case SND_SOC_DAIFMT_IB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - ssicr |= CR_SWSP; /* word select starts low */ - break; - default: - pr_debug("ssi: invalid inversion\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_BC_FC: - break; - case SND_SOC_DAIFMT_BP_FC: - ssicr |= CR_SCK_MASTER; - break; - case SND_SOC_DAIFMT_BC_FP: - ssicr |= CR_SWS_MASTER; - break; - case SND_SOC_DAIFMT_BP_FP: - ssicr |= CR_SWS_MASTER | CR_SCK_MASTER; - break; - default: - pr_debug("ssi: invalid master/secondary configuration\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr); - - return 0; -} - -/* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in - * Master mode, so really this is board specific; the SSI can do any - * rate with the right bitclk and divider settings. - */ -#define SSI_RATES \ - SNDRV_PCM_RATE_8000_192000 - -/* the SSI can do 8-32 bit samples, with 8 possible channels */ -#define SSI_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) - -static const struct snd_soc_dai_ops ssi_dai_ops = { - .startup = ssi_startup, - .shutdown = ssi_shutdown, - .trigger = ssi_trigger, - .hw_params = ssi_hw_params, - .set_sysclk = ssi_set_sysclk, - .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, -}; - -static struct snd_soc_dai_driver sh4_ssi_dai[] = { -{ - .name = "ssi-dai.0", - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = &ssi_dai_ops, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "ssi-dai.1", - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = &ssi_dai_ops, -}, -#endif -}; - -static const struct snd_soc_component_driver sh4_ssi_component = { - .name = "sh4-ssi", - .legacy_dai_naming = 1, -}; - -static int sh4_soc_dai_probe(struct platform_device *pdev) -{ - return devm_snd_soc_register_component(&pdev->dev, &sh4_ssi_component, - sh4_ssi_dai, - ARRAY_SIZE(sh4_ssi_dai)); -} - -static struct platform_driver sh4_ssi_driver = { - .driver = { - .name = "sh4-ssi-dai", - }, - - .probe = sh4_soc_dai_probe, -}; - -module_platform_driver(sh4_ssi_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); From patchwork Fri Jan 13 06:23:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642553 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F07A4C678DE for ; Fri, 13 Jan 2023 06:28:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241011AbjAMG2I (ORCPT ); Fri, 13 Jan 2023 01:28:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33490 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234671AbjAMGYw (ORCPT ); Fri, 13 Jan 2023 01:24:52 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 41A176AD8E; Thu, 12 Jan 2023 22:24:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=iaAi+zESrNMNvvfEXFwVvV/C96H0o/Wg4Lh/ijTH/Rs=; b=bFRj3MYFOTjA0PSj1DEyvNksix /txq5zuehZaq1Obp5gHKz5id8DzeGGV7lKL1AlhZOUgWtvxuhMVAbMwGri/ic3+f0enD9lYjxMQxR Gf9Y2f2aOQpWUPFvfhpJhFzN7A8d5hLtjyalZeqPDUM7QjO4XAjWCeiOpKaBwU207o9TIBRxH7mXv 9vW0R9Uv9WQi52i2Oie2Pb8ur8xtcT8EDzxlRsm/eP88LuKtf9xnY5QQhes6Rk2Hh9F25LQMh2HOL FXdK9tEz8XfVNXQMf+wriv4ySdq3dT2hm7Zg5AxsfkPpD1KGm+e/o6nTrxQgdrQp+txMqv4euPuCk mWxG2tow==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDU1-000lXq-5b; Fri, 13 Jan 2023 06:24:09 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 07/22] cpufreq: remove the sh-cpufreq driver Date: Fri, 13 Jan 2023 07:23:24 +0100 Message-Id: <20230113062339.1909087-8-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/cpufreq/Kconfig | 14 --- drivers/cpufreq/Makefile | 1 - drivers/cpufreq/sh-cpufreq.c | 175 ----------------------------------- 3 files changed, 190 deletions(-) delete mode 100644 drivers/cpufreq/sh-cpufreq.c diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 2a84fc63371e2e..75a7a486308d8c 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -298,20 +298,6 @@ config SPARC_US2E_CPUFREQ If in doubt, say N. endif -if SUPERH -config SH_CPU_FREQ - tristate "SuperH CPU Frequency driver" - help - This adds the cpufreq driver for SuperH. Any CPU that supports - clock rate rounding through the clock framework can use this - driver. While it will make the kernel slightly larger, this is - harmless for CPUs that don't support rate rounding. The driver - will also generate a notice in the boot log before disabling - itself if the CPU in question is not capable of rate rounding. - - If unsure, say N. -endif - config QORIQ_CPUFREQ tristate "CPU frequency scaling driver for Freescale QorIQ SoCs" depends on OF && COMMON_CLK diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 32a7029e25ed81..9c16e77e3e87c0 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -112,6 +112,5 @@ obj-$(CONFIG_BMIPS_CPUFREQ) += bmips-cpufreq.o obj-$(CONFIG_IA64_ACPI_CPUFREQ) += ia64-acpi-cpufreq.o obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o obj-$(CONFIG_LOONGSON1_CPUFREQ) += loongson1-cpufreq.o -obj-$(CONFIG_SH_CPU_FREQ) += sh-cpufreq.o obj-$(CONFIG_SPARC_US2E_CPUFREQ) += sparc-us2e-cpufreq.o obj-$(CONFIG_SPARC_US3_CPUFREQ) += sparc-us3-cpufreq.o diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c deleted file mode 100644 index b8704232c27b24..00000000000000 --- a/drivers/cpufreq/sh-cpufreq.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * cpufreq driver for the SuperH processors. - * - * Copyright (C) 2002 - 2012 Paul Mundt - * Copyright (C) 2002 M. R. Brown - * - * Clock framework bits from arch/avr32/mach-at32ap/cpufreq.c - * - * Copyright (C) 2004-2007 Atmel Corporation - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "cpufreq: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static DEFINE_PER_CPU(struct clk, sh_cpuclk); - -struct cpufreq_target { - struct cpufreq_policy *policy; - unsigned int freq; -}; - -static unsigned int sh_cpufreq_get(unsigned int cpu) -{ - return (clk_get_rate(&per_cpu(sh_cpuclk, cpu)) + 500) / 1000; -} - -static long __sh_cpufreq_target(void *arg) -{ - struct cpufreq_target *target = arg; - struct cpufreq_policy *policy = target->policy; - int cpu = policy->cpu; - struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); - struct cpufreq_freqs freqs; - struct device *dev; - long freq; - - if (smp_processor_id() != cpu) - return -ENODEV; - - dev = get_cpu_device(cpu); - - /* Convert target_freq from kHz to Hz */ - freq = clk_round_rate(cpuclk, target->freq * 1000); - - if (freq < (policy->min * 1000) || freq > (policy->max * 1000)) - return -EINVAL; - - dev_dbg(dev, "requested frequency %u Hz\n", target->freq * 1000); - - freqs.old = sh_cpufreq_get(cpu); - freqs.new = (freq + 500) / 1000; - freqs.flags = 0; - - cpufreq_freq_transition_begin(target->policy, &freqs); - clk_set_rate(cpuclk, freq); - cpufreq_freq_transition_end(target->policy, &freqs, 0); - - dev_dbg(dev, "set frequency %lu Hz\n", freq); - return 0; -} - -/* - * Here we notify other drivers of the proposed change and the final change. - */ -static int sh_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - struct cpufreq_target data = { .policy = policy, .freq = target_freq }; - - return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data); -} - -static int sh_cpufreq_verify(struct cpufreq_policy_data *policy) -{ - struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu); - struct cpufreq_frequency_table *freq_table; - - freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL; - if (freq_table) - return cpufreq_frequency_table_verify(policy, freq_table); - - cpufreq_verify_within_cpu_limits(policy); - - policy->min = (clk_round_rate(cpuclk, 1) + 500) / 1000; - policy->max = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; - - cpufreq_verify_within_cpu_limits(policy); - return 0; -} - -static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int cpu = policy->cpu; - struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); - struct cpufreq_frequency_table *freq_table; - struct device *dev; - - dev = get_cpu_device(cpu); - - cpuclk = clk_get(dev, "cpu_clk"); - if (IS_ERR(cpuclk)) { - dev_err(dev, "couldn't get CPU clk\n"); - return PTR_ERR(cpuclk); - } - - freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL; - if (freq_table) { - policy->freq_table = freq_table; - } else { - dev_notice(dev, "no frequency table found, falling back " - "to rate rounding.\n"); - - policy->min = policy->cpuinfo.min_freq = - (clk_round_rate(cpuclk, 1) + 500) / 1000; - policy->max = policy->cpuinfo.max_freq = - (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; - } - - return 0; -} - -static int sh_cpufreq_cpu_exit(struct cpufreq_policy *policy) -{ - unsigned int cpu = policy->cpu; - struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); - - clk_put(cpuclk); - - return 0; -} - -static struct cpufreq_driver sh_cpufreq_driver = { - .name = "sh", - .flags = CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING, - .get = sh_cpufreq_get, - .target = sh_cpufreq_target, - .verify = sh_cpufreq_verify, - .init = sh_cpufreq_cpu_init, - .exit = sh_cpufreq_cpu_exit, - .attr = cpufreq_generic_attr, -}; - -static int __init sh_cpufreq_module_init(void) -{ - pr_notice("SuperH CPU frequency driver.\n"); - return cpufreq_register_driver(&sh_cpufreq_driver); -} - -static void __exit sh_cpufreq_module_exit(void) -{ - cpufreq_unregister_driver(&sh_cpufreq_driver); -} - -module_init(sh_cpufreq_module_init); -module_exit(sh_cpufreq_module_exit); - -MODULE_AUTHOR("Paul Mundt "); -MODULE_DESCRIPTION("cpufreq driver for SuperH"); -MODULE_LICENSE("GPL"); From patchwork Fri Jan 13 06:23:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642548 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 278FDC54EBD for ; Fri, 13 Jan 2023 06:31:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232602AbjAMGbJ (ORCPT ); Fri, 13 Jan 2023 01:31:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240122AbjAMGZG (ORCPT ); Fri, 13 Jan 2023 01:25:06 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 888386AD81; Thu, 12 Jan 2023 22:24:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=uYJHAXXmLLwNQhTzaxgylPcAhRmrIofyohyZoeMvH6A=; b=O9iHd8tTAdld8bSk+ZYkR0XYZy 2FuVzfaL8+QL6xMnlPS9ImDdfrVmrsT0bBu6ltAfdqg3tZ8KHWyQj3fcy7LsIMSUyZEf4JyF1NO/u 2Ts4+jOpsmzngPoutWMosurrp3mGqo1ovVKSnCoZsYAwo0uVYE6mREk0pxLXWhs9KHUyyY4RrDi1s ckbuJtm4E90O4qjKhGszRSFnFx2n1e7KSOOiE2NOT+ddsS+UK8qKQjoMHxsg7UASbpmlsrI2MUcNr U3LKQcwW662AanMhRCQ9l+fUskCCYGWjf3f0p00y4z00yMr4itbMdi+aRN3kbJr3aDbphSgt4Qqgh s26wPgJg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDU4-000lZR-IG; Fri, 13 Jan 2023 06:24:13 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 08/22] dmaengine: remove the shdmac driver Date: Fri, 13 Jan 2023 07:23:25 +0100 Message-Id: <20230113062339.1909087-9-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/dma/sh/Kconfig | 20 - drivers/dma/sh/Makefile | 13 - drivers/dma/sh/shdma-base.c | 1052 ----------------------------------- drivers/dma/sh/shdma.h | 61 -- drivers/dma/sh/shdmac.c | 938 ------------------------------- include/linux/shdma-base.h | 4 - 6 files changed, 2088 deletions(-) delete mode 100644 drivers/dma/sh/shdma-base.c delete mode 100644 drivers/dma/sh/shdma.h delete mode 100644 drivers/dma/sh/shdmac.c diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig index c0b2997ab7fd93..744d4d8ff5353b 100644 --- a/drivers/dma/sh/Kconfig +++ b/drivers/dma/sh/Kconfig @@ -7,30 +7,10 @@ config RENESAS_DMA bool select DMA_ENGINE -# -# DMA Engine Helpers -# - -config SH_DMAE_BASE - bool "Renesas SuperH DMA Engine support" - depends on SUPERH || COMPILE_TEST - depends on !SUPERH || SH_DMA - depends on !SH_DMA_API - default y - select RENESAS_DMA - help - Enable support for the Renesas SuperH DMA controllers. - # # DMA Controllers # -config SH_DMAE - tristate "Renesas SuperH DMAC support" - depends on SH_DMAE_BASE - help - Enable support for the Renesas SuperH DMA controllers. - config RCAR_DMAC tristate "Renesas R-Car Gen{2,3} and RZ/G{1,2} DMA Controller" depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile index 360ab6d25e769d..07178651aa7279 100644 --- a/drivers/dma/sh/Makefile +++ b/drivers/dma/sh/Makefile @@ -1,17 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -# -# DMA Engine Helpers -# - -obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o - -# -# DMA Controllers -# - -shdma-y := shdmac.o -shdma-objs := $(shdma-y) -obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_RCAR_DMAC) += rcar-dmac.o obj-$(CONFIG_RENESAS_USB_DMAC) += usb-dmac.o diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c deleted file mode 100644 index 158e5e7defaeb0..00000000000000 --- a/drivers/dma/sh/shdma-base.c +++ /dev/null @@ -1,1052 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Dmaengine driver base library for DMA controllers, found on SH-based SoCs - * - * extracted from shdma.c - * - * Copyright (C) 2011-2012 Guennadi Liakhovetski - * Copyright (C) 2009 Nobuhiro Iwamatsu - * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved. - * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../dmaengine.h" - -/* DMA descriptor control */ -enum shdma_desc_status { - DESC_IDLE, - DESC_PREPARED, - DESC_SUBMITTED, - DESC_COMPLETED, /* completed, have to call callback */ - DESC_WAITING, /* callback called, waiting for ack / re-submit */ -}; - -#define NR_DESCS_PER_CHANNEL 32 - -#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan) -#define to_shdma_dev(d) container_of(d, struct shdma_dev, dma_dev) - -/* - * For slave DMA we assume, that there is a finite number of DMA slaves in the - * system, and that each such slave can only use a finite number of channels. - * We use slave channel IDs to make sure, that no such slave channel ID is - * allocated more than once. - */ -static unsigned int slave_num = 256; -module_param(slave_num, uint, 0444); - -/* A bitmask with slave_num bits */ -static unsigned long *shdma_slave_used; - -/* Called under spin_lock_irq(&schan->chan_lock") */ -static void shdma_chan_xfer_ld_queue(struct shdma_chan *schan) -{ - struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); - const struct shdma_ops *ops = sdev->ops; - struct shdma_desc *sdesc; - - /* DMA work check */ - if (ops->channel_busy(schan)) - return; - - /* Find the first not transferred descriptor */ - list_for_each_entry(sdesc, &schan->ld_queue, node) - if (sdesc->mark == DESC_SUBMITTED) { - ops->start_xfer(schan, sdesc); - break; - } -} - -static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) -{ - struct shdma_desc *chunk, *c, *desc = - container_of(tx, struct shdma_desc, async_tx); - struct shdma_chan *schan = to_shdma_chan(tx->chan); - dma_async_tx_callback callback = tx->callback; - dma_cookie_t cookie; - bool power_up; - - spin_lock_irq(&schan->chan_lock); - - power_up = list_empty(&schan->ld_queue); - - cookie = dma_cookie_assign(tx); - - /* Mark all chunks of this descriptor as submitted, move to the queue */ - list_for_each_entry_safe(chunk, c, desc->node.prev, node) { - /* - * All chunks are on the global ld_free, so, we have to find - * the end of the chain ourselves - */ - if (chunk != desc && (chunk->mark == DESC_IDLE || - chunk->async_tx.cookie > 0 || - chunk->async_tx.cookie == -EBUSY || - &chunk->node == &schan->ld_free)) - break; - chunk->mark = DESC_SUBMITTED; - if (chunk->chunks == 1) { - chunk->async_tx.callback = callback; - chunk->async_tx.callback_param = tx->callback_param; - } else { - /* Callback goes to the last chunk */ - chunk->async_tx.callback = NULL; - } - chunk->cookie = cookie; - list_move_tail(&chunk->node, &schan->ld_queue); - - dev_dbg(schan->dev, "submit #%d@%p on %d\n", - tx->cookie, &chunk->async_tx, schan->id); - } - - if (power_up) { - int ret; - schan->pm_state = SHDMA_PM_BUSY; - - ret = pm_runtime_get(schan->dev); - - spin_unlock_irq(&schan->chan_lock); - if (ret < 0) - dev_err(schan->dev, "%s(): GET = %d\n", __func__, ret); - - pm_runtime_barrier(schan->dev); - - spin_lock_irq(&schan->chan_lock); - - /* Have we been reset, while waiting? */ - if (schan->pm_state != SHDMA_PM_ESTABLISHED) { - struct shdma_dev *sdev = - to_shdma_dev(schan->dma_chan.device); - const struct shdma_ops *ops = sdev->ops; - dev_dbg(schan->dev, "Bring up channel %d\n", - schan->id); - /* - * TODO: .xfer_setup() might fail on some platforms. - * Make it int then, on error remove chunks from the - * queue again - */ - ops->setup_xfer(schan, schan->slave_id); - - if (schan->pm_state == SHDMA_PM_PENDING) - shdma_chan_xfer_ld_queue(schan); - schan->pm_state = SHDMA_PM_ESTABLISHED; - } - } else { - /* - * Tell .device_issue_pending() not to run the queue, interrupts - * will do it anyway - */ - schan->pm_state = SHDMA_PM_PENDING; - } - - spin_unlock_irq(&schan->chan_lock); - - return cookie; -} - -/* Called with desc_lock held */ -static struct shdma_desc *shdma_get_desc(struct shdma_chan *schan) -{ - struct shdma_desc *sdesc; - - list_for_each_entry(sdesc, &schan->ld_free, node) - if (sdesc->mark != DESC_PREPARED) { - BUG_ON(sdesc->mark != DESC_IDLE); - list_del(&sdesc->node); - return sdesc; - } - - return NULL; -} - -static int shdma_setup_slave(struct shdma_chan *schan, dma_addr_t slave_addr) -{ - struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); - const struct shdma_ops *ops = sdev->ops; - int ret, match; - - if (schan->dev->of_node) { - match = schan->hw_req; - ret = ops->set_slave(schan, match, slave_addr, true); - if (ret < 0) - return ret; - } else { - match = schan->real_slave_id; - } - - if (schan->real_slave_id < 0 || schan->real_slave_id >= slave_num) - return -EINVAL; - - if (test_and_set_bit(schan->real_slave_id, shdma_slave_used)) - return -EBUSY; - - ret = ops->set_slave(schan, match, slave_addr, false); - if (ret < 0) { - clear_bit(schan->real_slave_id, shdma_slave_used); - return ret; - } - - schan->slave_id = schan->real_slave_id; - - return 0; -} - -static int shdma_alloc_chan_resources(struct dma_chan *chan) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); - const struct shdma_ops *ops = sdev->ops; - struct shdma_desc *desc; - struct shdma_slave *slave = chan->private; - int ret, i; - - /* - * This relies on the guarantee from dmaengine that alloc_chan_resources - * never runs concurrently with itself or free_chan_resources. - */ - if (slave) { - /* Legacy mode: .private is set in filter */ - schan->real_slave_id = slave->slave_id; - ret = shdma_setup_slave(schan, 0); - if (ret < 0) - goto esetslave; - } else { - /* Normal mode: real_slave_id was set by filter */ - schan->slave_id = -EINVAL; - } - - schan->desc = kcalloc(NR_DESCS_PER_CHANNEL, - sdev->desc_size, GFP_KERNEL); - if (!schan->desc) { - ret = -ENOMEM; - goto edescalloc; - } - schan->desc_num = NR_DESCS_PER_CHANNEL; - - for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) { - desc = ops->embedded_desc(schan->desc, i); - dma_async_tx_descriptor_init(&desc->async_tx, - &schan->dma_chan); - desc->async_tx.tx_submit = shdma_tx_submit; - desc->mark = DESC_IDLE; - - list_add(&desc->node, &schan->ld_free); - } - - return NR_DESCS_PER_CHANNEL; - -edescalloc: - if (slave) -esetslave: - clear_bit(slave->slave_id, shdma_slave_used); - chan->private = NULL; - return ret; -} - -/* - * This is the standard shdma filter function to be used as a replacement to the - * "old" method, using the .private pointer. - * You always have to pass a valid slave id as the argument, old drivers that - * pass ERR_PTR(-EINVAL) as a filter parameter and set it up in dma_slave_config - * need to be updated so we can remove the slave_id field from dma_slave_config. - * parameter. If this filter is used, the slave driver, after calling - * dma_request_channel(), will also have to call dmaengine_slave_config() with - * .direction, and either .src_addr or .dst_addr set. - * - * NOTE: this filter doesn't support multiple DMAC drivers with the DMA_SLAVE - * capability! If this becomes a requirement, hardware glue drivers, using this - * services would have to provide their own filters, which first would check - * the device driver, similar to how other DMAC drivers, e.g., sa11x0-dma.c, do - * this, and only then, in case of a match, call this common filter. - * NOTE 2: This filter function is also used in the DT case by shdma_of_xlate(). - * In that case the MID-RID value is used for slave channel filtering and is - * passed to this function in the "arg" parameter. - */ -bool shdma_chan_filter(struct dma_chan *chan, void *arg) -{ - struct shdma_chan *schan; - struct shdma_dev *sdev; - int slave_id = (long)arg; - int ret; - - /* Only support channels handled by this driver. */ - if (chan->device->device_alloc_chan_resources != - shdma_alloc_chan_resources) - return false; - - schan = to_shdma_chan(chan); - sdev = to_shdma_dev(chan->device); - - /* - * For DT, the schan->slave_id field is generated by the - * set_slave function from the slave ID that is passed in - * from xlate. For the non-DT case, the slave ID is - * directly passed into the filter function by the driver - */ - if (schan->dev->of_node) { - ret = sdev->ops->set_slave(schan, slave_id, 0, true); - if (ret < 0) - return false; - - schan->real_slave_id = schan->slave_id; - return true; - } - - if (slave_id < 0) { - /* No slave requested - arbitrary channel */ - dev_warn(sdev->dma_dev.dev, "invalid slave ID passed to dma_request_slave\n"); - return true; - } - - if (slave_id >= slave_num) - return false; - - ret = sdev->ops->set_slave(schan, slave_id, 0, true); - if (ret < 0) - return false; - - schan->real_slave_id = slave_id; - - return true; -} -EXPORT_SYMBOL(shdma_chan_filter); - -static dma_async_tx_callback __ld_cleanup(struct shdma_chan *schan, bool all) -{ - struct shdma_desc *desc, *_desc; - /* Is the "exposed" head of a chain acked? */ - bool head_acked = false; - dma_cookie_t cookie = 0; - dma_async_tx_callback callback = NULL; - struct dmaengine_desc_callback cb; - unsigned long flags; - LIST_HEAD(cyclic_list); - - memset(&cb, 0, sizeof(cb)); - spin_lock_irqsave(&schan->chan_lock, flags); - list_for_each_entry_safe(desc, _desc, &schan->ld_queue, node) { - struct dma_async_tx_descriptor *tx = &desc->async_tx; - - BUG_ON(tx->cookie > 0 && tx->cookie != desc->cookie); - BUG_ON(desc->mark != DESC_SUBMITTED && - desc->mark != DESC_COMPLETED && - desc->mark != DESC_WAITING); - - /* - * queue is ordered, and we use this loop to (1) clean up all - * completed descriptors, and to (2) update descriptor flags of - * any chunks in a (partially) completed chain - */ - if (!all && desc->mark == DESC_SUBMITTED && - desc->cookie != cookie) - break; - - if (tx->cookie > 0) - cookie = tx->cookie; - - if (desc->mark == DESC_COMPLETED && desc->chunks == 1) { - if (schan->dma_chan.completed_cookie != desc->cookie - 1) - dev_dbg(schan->dev, - "Completing cookie %d, expected %d\n", - desc->cookie, - schan->dma_chan.completed_cookie + 1); - schan->dma_chan.completed_cookie = desc->cookie; - } - - /* Call callback on the last chunk */ - if (desc->mark == DESC_COMPLETED && tx->callback) { - desc->mark = DESC_WAITING; - dmaengine_desc_get_callback(tx, &cb); - callback = tx->callback; - dev_dbg(schan->dev, "descriptor #%d@%p on %d callback\n", - tx->cookie, tx, schan->id); - BUG_ON(desc->chunks != 1); - break; - } - - if (tx->cookie > 0 || tx->cookie == -EBUSY) { - if (desc->mark == DESC_COMPLETED) { - BUG_ON(tx->cookie < 0); - desc->mark = DESC_WAITING; - } - head_acked = async_tx_test_ack(tx); - } else { - switch (desc->mark) { - case DESC_COMPLETED: - desc->mark = DESC_WAITING; - fallthrough; - case DESC_WAITING: - if (head_acked) - async_tx_ack(&desc->async_tx); - } - } - - dev_dbg(schan->dev, "descriptor %p #%d completed.\n", - tx, tx->cookie); - - if (((desc->mark == DESC_COMPLETED || - desc->mark == DESC_WAITING) && - async_tx_test_ack(&desc->async_tx)) || all) { - - if (all || !desc->cyclic) { - /* Remove from ld_queue list */ - desc->mark = DESC_IDLE; - list_move(&desc->node, &schan->ld_free); - } else { - /* reuse as cyclic */ - desc->mark = DESC_SUBMITTED; - list_move_tail(&desc->node, &cyclic_list); - } - - if (list_empty(&schan->ld_queue)) { - dev_dbg(schan->dev, "Bring down channel %d\n", schan->id); - pm_runtime_put(schan->dev); - schan->pm_state = SHDMA_PM_ESTABLISHED; - } else if (schan->pm_state == SHDMA_PM_PENDING) { - shdma_chan_xfer_ld_queue(schan); - } - } - } - - if (all && !callback) - /* - * Terminating and the loop completed normally: forgive - * uncompleted cookies - */ - schan->dma_chan.completed_cookie = schan->dma_chan.cookie; - - list_splice_tail(&cyclic_list, &schan->ld_queue); - - spin_unlock_irqrestore(&schan->chan_lock, flags); - - dmaengine_desc_callback_invoke(&cb, NULL); - - return callback; -} - -/* - * shdma_chan_ld_cleanup - Clean up link descriptors - * - * Clean up the ld_queue of DMA channel. - */ -static void shdma_chan_ld_cleanup(struct shdma_chan *schan, bool all) -{ - while (__ld_cleanup(schan, all)) - ; -} - -/* - * shdma_free_chan_resources - Free all resources of the channel. - */ -static void shdma_free_chan_resources(struct dma_chan *chan) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - struct shdma_dev *sdev = to_shdma_dev(chan->device); - const struct shdma_ops *ops = sdev->ops; - LIST_HEAD(list); - - /* Protect against ISR */ - spin_lock_irq(&schan->chan_lock); - ops->halt_channel(schan); - spin_unlock_irq(&schan->chan_lock); - - /* Now no new interrupts will occur */ - - /* Prepared and not submitted descriptors can still be on the queue */ - if (!list_empty(&schan->ld_queue)) - shdma_chan_ld_cleanup(schan, true); - - if (schan->slave_id >= 0) { - /* The caller is holding dma_list_mutex */ - clear_bit(schan->slave_id, shdma_slave_used); - chan->private = NULL; - } - - schan->real_slave_id = 0; - - spin_lock_irq(&schan->chan_lock); - - list_splice_init(&schan->ld_free, &list); - schan->desc_num = 0; - - spin_unlock_irq(&schan->chan_lock); - - kfree(schan->desc); -} - -/** - * shdma_add_desc - get, set up and return one transfer descriptor - * @schan: DMA channel - * @flags: DMA transfer flags - * @dst: destination DMA address, incremented when direction equals - * DMA_DEV_TO_MEM or DMA_MEM_TO_MEM - * @src: source DMA address, incremented when direction equals - * DMA_MEM_TO_DEV or DMA_MEM_TO_MEM - * @len: DMA transfer length - * @first: if NULL, set to the current descriptor and cookie set to -EBUSY - * @direction: needed for slave DMA to decide which address to keep constant, - * equals DMA_MEM_TO_MEM for MEMCPY - * Returns 0 or an error - * Locks: called with desc_lock held - */ -static struct shdma_desc *shdma_add_desc(struct shdma_chan *schan, - unsigned long flags, dma_addr_t *dst, dma_addr_t *src, size_t *len, - struct shdma_desc **first, enum dma_transfer_direction direction) -{ - struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); - const struct shdma_ops *ops = sdev->ops; - struct shdma_desc *new; - size_t copy_size = *len; - - if (!copy_size) - return NULL; - - /* Allocate the link descriptor from the free list */ - new = shdma_get_desc(schan); - if (!new) { - dev_err(schan->dev, "No free link descriptor available\n"); - return NULL; - } - - ops->desc_setup(schan, new, *src, *dst, ©_size); - - if (!*first) { - /* First desc */ - new->async_tx.cookie = -EBUSY; - *first = new; - } else { - /* Other desc - invisible to the user */ - new->async_tx.cookie = -EINVAL; - } - - dev_dbg(schan->dev, - "chaining (%zu/%zu)@%pad -> %pad with %p, cookie %d\n", - copy_size, *len, src, dst, &new->async_tx, - new->async_tx.cookie); - - new->mark = DESC_PREPARED; - new->async_tx.flags = flags; - new->direction = direction; - new->partial = 0; - - *len -= copy_size; - if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV) - *src += copy_size; - if (direction == DMA_MEM_TO_MEM || direction == DMA_DEV_TO_MEM) - *dst += copy_size; - - return new; -} - -/* - * shdma_prep_sg - prepare transfer descriptors from an SG list - * - * Common routine for public (MEMCPY) and slave DMA. The MEMCPY case is also - * converted to scatter-gather to guarantee consistent locking and a correct - * list manipulation. For slave DMA direction carries the usual meaning, and, - * logically, the SG list is RAM and the addr variable contains slave address, - * e.g., the FIFO I/O register. For MEMCPY direction equals DMA_MEM_TO_MEM - * and the SG list contains only one element and points at the source buffer. - */ -static struct dma_async_tx_descriptor *shdma_prep_sg(struct shdma_chan *schan, - struct scatterlist *sgl, unsigned int sg_len, dma_addr_t *addr, - enum dma_transfer_direction direction, unsigned long flags, bool cyclic) -{ - struct scatterlist *sg; - struct shdma_desc *first = NULL, *new = NULL /* compiler... */; - LIST_HEAD(tx_list); - int chunks = 0; - unsigned long irq_flags; - int i; - - for_each_sg(sgl, sg, sg_len, i) - chunks += DIV_ROUND_UP(sg_dma_len(sg), schan->max_xfer_len); - - /* Have to lock the whole loop to protect against concurrent release */ - spin_lock_irqsave(&schan->chan_lock, irq_flags); - - /* - * Chaining: - * first descriptor is what user is dealing with in all API calls, its - * cookie is at first set to -EBUSY, at tx-submit to a positive - * number - * if more than one chunk is needed further chunks have cookie = -EINVAL - * the last chunk, if not equal to the first, has cookie = -ENOSPC - * all chunks are linked onto the tx_list head with their .node heads - * only during this function, then they are immediately spliced - * back onto the free list in form of a chain - */ - for_each_sg(sgl, sg, sg_len, i) { - dma_addr_t sg_addr = sg_dma_address(sg); - size_t len = sg_dma_len(sg); - - if (!len) - goto err_get_desc; - - do { - dev_dbg(schan->dev, "Add SG #%d@%p[%zu], dma %pad\n", - i, sg, len, &sg_addr); - - if (direction == DMA_DEV_TO_MEM) - new = shdma_add_desc(schan, flags, - &sg_addr, addr, &len, &first, - direction); - else - new = shdma_add_desc(schan, flags, - addr, &sg_addr, &len, &first, - direction); - if (!new) - goto err_get_desc; - - new->cyclic = cyclic; - if (cyclic) - new->chunks = 1; - else - new->chunks = chunks--; - list_add_tail(&new->node, &tx_list); - } while (len); - } - - if (new != first) - new->async_tx.cookie = -ENOSPC; - - /* Put them back on the free list, so, they don't get lost */ - list_splice_tail(&tx_list, &schan->ld_free); - - spin_unlock_irqrestore(&schan->chan_lock, irq_flags); - - return &first->async_tx; - -err_get_desc: - list_for_each_entry(new, &tx_list, node) - new->mark = DESC_IDLE; - list_splice(&tx_list, &schan->ld_free); - - spin_unlock_irqrestore(&schan->chan_lock, irq_flags); - - return NULL; -} - -static struct dma_async_tx_descriptor *shdma_prep_memcpy( - struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src, - size_t len, unsigned long flags) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - struct scatterlist sg; - - if (!chan || !len) - return NULL; - - BUG_ON(!schan->desc_num); - - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(dma_src)), len, - offset_in_page(dma_src)); - sg_dma_address(&sg) = dma_src; - sg_dma_len(&sg) = len; - - return shdma_prep_sg(schan, &sg, 1, &dma_dest, DMA_MEM_TO_MEM, - flags, false); -} - -static struct dma_async_tx_descriptor *shdma_prep_slave_sg( - struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, - enum dma_transfer_direction direction, unsigned long flags, void *context) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); - const struct shdma_ops *ops = sdev->ops; - int slave_id = schan->slave_id; - dma_addr_t slave_addr; - - if (!chan) - return NULL; - - BUG_ON(!schan->desc_num); - - /* Someone calling slave DMA on a generic channel? */ - if (slave_id < 0 || !sg_len) { - dev_warn(schan->dev, "%s: bad parameter: len=%d, id=%d\n", - __func__, sg_len, slave_id); - return NULL; - } - - slave_addr = ops->slave_addr(schan); - - return shdma_prep_sg(schan, sgl, sg_len, &slave_addr, - direction, flags, false); -} - -#define SHDMA_MAX_SG_LEN 32 - -static struct dma_async_tx_descriptor *shdma_prep_dma_cyclic( - struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, - size_t period_len, enum dma_transfer_direction direction, - unsigned long flags) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); - struct dma_async_tx_descriptor *desc; - const struct shdma_ops *ops = sdev->ops; - unsigned int sg_len = buf_len / period_len; - int slave_id = schan->slave_id; - dma_addr_t slave_addr; - struct scatterlist *sgl; - int i; - - if (!chan) - return NULL; - - BUG_ON(!schan->desc_num); - - if (sg_len > SHDMA_MAX_SG_LEN) { - dev_err(schan->dev, "sg length %d exceeds limit %d", - sg_len, SHDMA_MAX_SG_LEN); - return NULL; - } - - /* Someone calling slave DMA on a generic channel? */ - if (slave_id < 0 || (buf_len < period_len)) { - dev_warn(schan->dev, - "%s: bad parameter: buf_len=%zu, period_len=%zu, id=%d\n", - __func__, buf_len, period_len, slave_id); - return NULL; - } - - slave_addr = ops->slave_addr(schan); - - /* - * Allocate the sg list dynamically as it would consumer too much stack - * space. - */ - sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_KERNEL); - if (!sgl) - return NULL; - - sg_init_table(sgl, sg_len); - - for (i = 0; i < sg_len; i++) { - dma_addr_t src = buf_addr + (period_len * i); - - sg_set_page(&sgl[i], pfn_to_page(PFN_DOWN(src)), period_len, - offset_in_page(src)); - sg_dma_address(&sgl[i]) = src; - sg_dma_len(&sgl[i]) = period_len; - } - - desc = shdma_prep_sg(schan, sgl, sg_len, &slave_addr, - direction, flags, true); - - kfree(sgl); - return desc; -} - -static int shdma_terminate_all(struct dma_chan *chan) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - struct shdma_dev *sdev = to_shdma_dev(chan->device); - const struct shdma_ops *ops = sdev->ops; - unsigned long flags; - - spin_lock_irqsave(&schan->chan_lock, flags); - ops->halt_channel(schan); - - if (ops->get_partial && !list_empty(&schan->ld_queue)) { - /* Record partial transfer */ - struct shdma_desc *desc = list_first_entry(&schan->ld_queue, - struct shdma_desc, node); - desc->partial = ops->get_partial(schan, desc); - } - - spin_unlock_irqrestore(&schan->chan_lock, flags); - - shdma_chan_ld_cleanup(schan, true); - - return 0; -} - -static int shdma_config(struct dma_chan *chan, - struct dma_slave_config *config) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - - /* - * So far only .slave_id is used, but the slave drivers are - * encouraged to also set a transfer direction and an address. - */ - if (!config) - return -EINVAL; - - /* - * We could lock this, but you shouldn't be configuring the - * channel, while using it... - */ - return shdma_setup_slave(schan, - config->direction == DMA_DEV_TO_MEM ? - config->src_addr : config->dst_addr); -} - -static void shdma_issue_pending(struct dma_chan *chan) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - - spin_lock_irq(&schan->chan_lock); - if (schan->pm_state == SHDMA_PM_ESTABLISHED) - shdma_chan_xfer_ld_queue(schan); - else - schan->pm_state = SHDMA_PM_PENDING; - spin_unlock_irq(&schan->chan_lock); -} - -static enum dma_status shdma_tx_status(struct dma_chan *chan, - dma_cookie_t cookie, - struct dma_tx_state *txstate) -{ - struct shdma_chan *schan = to_shdma_chan(chan); - enum dma_status status; - unsigned long flags; - - shdma_chan_ld_cleanup(schan, false); - - spin_lock_irqsave(&schan->chan_lock, flags); - - status = dma_cookie_status(chan, cookie, txstate); - - /* - * If we don't find cookie on the queue, it has been aborted and we have - * to report error - */ - if (status != DMA_COMPLETE) { - struct shdma_desc *sdesc; - status = DMA_ERROR; - list_for_each_entry(sdesc, &schan->ld_queue, node) - if (sdesc->cookie == cookie) { - status = DMA_IN_PROGRESS; - break; - } - } - - spin_unlock_irqrestore(&schan->chan_lock, flags); - - return status; -} - -/* Called from error IRQ or NMI */ -bool shdma_reset(struct shdma_dev *sdev) -{ - const struct shdma_ops *ops = sdev->ops; - struct shdma_chan *schan; - unsigned int handled = 0; - int i; - - /* Reset all channels */ - shdma_for_each_chan(schan, sdev, i) { - struct shdma_desc *sdesc; - LIST_HEAD(dl); - - if (!schan) - continue; - - spin_lock(&schan->chan_lock); - - /* Stop the channel */ - ops->halt_channel(schan); - - list_splice_init(&schan->ld_queue, &dl); - - if (!list_empty(&dl)) { - dev_dbg(schan->dev, "Bring down channel %d\n", schan->id); - pm_runtime_put(schan->dev); - } - schan->pm_state = SHDMA_PM_ESTABLISHED; - - spin_unlock(&schan->chan_lock); - - /* Complete all */ - list_for_each_entry(sdesc, &dl, node) { - struct dma_async_tx_descriptor *tx = &sdesc->async_tx; - - sdesc->mark = DESC_IDLE; - dmaengine_desc_get_callback_invoke(tx, NULL); - } - - spin_lock(&schan->chan_lock); - list_splice(&dl, &schan->ld_free); - spin_unlock(&schan->chan_lock); - - handled++; - } - - return !!handled; -} -EXPORT_SYMBOL(shdma_reset); - -static irqreturn_t chan_irq(int irq, void *dev) -{ - struct shdma_chan *schan = dev; - const struct shdma_ops *ops = - to_shdma_dev(schan->dma_chan.device)->ops; - irqreturn_t ret; - - spin_lock(&schan->chan_lock); - - ret = ops->chan_irq(schan, irq) ? IRQ_WAKE_THREAD : IRQ_NONE; - - spin_unlock(&schan->chan_lock); - - return ret; -} - -static irqreturn_t chan_irqt(int irq, void *dev) -{ - struct shdma_chan *schan = dev; - const struct shdma_ops *ops = - to_shdma_dev(schan->dma_chan.device)->ops; - struct shdma_desc *sdesc; - - spin_lock_irq(&schan->chan_lock); - list_for_each_entry(sdesc, &schan->ld_queue, node) { - if (sdesc->mark == DESC_SUBMITTED && - ops->desc_completed(schan, sdesc)) { - dev_dbg(schan->dev, "done #%d@%p\n", - sdesc->async_tx.cookie, &sdesc->async_tx); - sdesc->mark = DESC_COMPLETED; - break; - } - } - /* Next desc */ - shdma_chan_xfer_ld_queue(schan); - spin_unlock_irq(&schan->chan_lock); - - shdma_chan_ld_cleanup(schan, false); - - return IRQ_HANDLED; -} - -int shdma_request_irq(struct shdma_chan *schan, int irq, - unsigned long flags, const char *name) -{ - int ret = devm_request_threaded_irq(schan->dev, irq, chan_irq, - chan_irqt, flags, name, schan); - - schan->irq = ret < 0 ? ret : irq; - - return ret; -} -EXPORT_SYMBOL(shdma_request_irq); - -void shdma_chan_probe(struct shdma_dev *sdev, - struct shdma_chan *schan, int id) -{ - schan->pm_state = SHDMA_PM_ESTABLISHED; - - /* reference struct dma_device */ - schan->dma_chan.device = &sdev->dma_dev; - dma_cookie_init(&schan->dma_chan); - - schan->dev = sdev->dma_dev.dev; - schan->id = id; - - if (!schan->max_xfer_len) - schan->max_xfer_len = PAGE_SIZE; - - spin_lock_init(&schan->chan_lock); - - /* Init descripter manage list */ - INIT_LIST_HEAD(&schan->ld_queue); - INIT_LIST_HEAD(&schan->ld_free); - - /* Add the channel to DMA device channel list */ - list_add_tail(&schan->dma_chan.device_node, - &sdev->dma_dev.channels); - sdev->schan[id] = schan; -} -EXPORT_SYMBOL(shdma_chan_probe); - -void shdma_chan_remove(struct shdma_chan *schan) -{ - list_del(&schan->dma_chan.device_node); -} -EXPORT_SYMBOL(shdma_chan_remove); - -int shdma_init(struct device *dev, struct shdma_dev *sdev, - int chan_num) -{ - struct dma_device *dma_dev = &sdev->dma_dev; - - /* - * Require all call-backs for now, they can trivially be made optional - * later as required - */ - if (!sdev->ops || - !sdev->desc_size || - !sdev->ops->embedded_desc || - !sdev->ops->start_xfer || - !sdev->ops->setup_xfer || - !sdev->ops->set_slave || - !sdev->ops->desc_setup || - !sdev->ops->slave_addr || - !sdev->ops->channel_busy || - !sdev->ops->halt_channel || - !sdev->ops->desc_completed) - return -EINVAL; - - sdev->schan = kcalloc(chan_num, sizeof(*sdev->schan), GFP_KERNEL); - if (!sdev->schan) - return -ENOMEM; - - INIT_LIST_HEAD(&dma_dev->channels); - - /* Common and MEMCPY operations */ - dma_dev->device_alloc_chan_resources - = shdma_alloc_chan_resources; - dma_dev->device_free_chan_resources = shdma_free_chan_resources; - dma_dev->device_prep_dma_memcpy = shdma_prep_memcpy; - dma_dev->device_tx_status = shdma_tx_status; - dma_dev->device_issue_pending = shdma_issue_pending; - - /* Compulsory for DMA_SLAVE fields */ - dma_dev->device_prep_slave_sg = shdma_prep_slave_sg; - dma_dev->device_prep_dma_cyclic = shdma_prep_dma_cyclic; - dma_dev->device_config = shdma_config; - dma_dev->device_terminate_all = shdma_terminate_all; - - dma_dev->dev = dev; - - return 0; -} -EXPORT_SYMBOL(shdma_init); - -void shdma_cleanup(struct shdma_dev *sdev) -{ - kfree(sdev->schan); -} -EXPORT_SYMBOL(shdma_cleanup); - -static int __init shdma_enter(void) -{ - shdma_slave_used = bitmap_zalloc(slave_num, GFP_KERNEL); - if (!shdma_slave_used) - return -ENOMEM; - return 0; -} -module_init(shdma_enter); - -static void __exit shdma_exit(void) -{ - bitmap_free(shdma_slave_used); -} -module_exit(shdma_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("SH-DMA driver base library"); -MODULE_AUTHOR("Guennadi Liakhovetski "); diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h deleted file mode 100644 index 9c121a4b33ad82..00000000000000 --- a/drivers/dma/sh/shdma.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Renesas SuperH DMA Engine support - * - * Copyright (C) 2009 Nobuhiro Iwamatsu - * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved. - * - */ -#ifndef __DMA_SHDMA_H -#define __DMA_SHDMA_H - -#include -#include -#include -#include -#include - -#define SH_DMAE_MAX_CHANNELS 20 -#define SH_DMAE_TCR_MAX 0x00FFFFFF /* 16MB */ - -struct device; - -struct sh_dmae_chan { - struct shdma_chan shdma_chan; - const struct sh_dmae_slave_config *config; /* Slave DMA configuration */ - int xmit_shift; /* log_2(bytes_per_xfer) */ - void __iomem *base; - char dev_id[16]; /* unique name per DMAC of channel */ - int pm_error; - dma_addr_t slave_addr; -}; - -struct sh_dmae_device { - struct shdma_dev shdma_dev; - struct sh_dmae_chan *chan[SH_DMAE_MAX_CHANNELS]; - const struct sh_dmae_pdata *pdata; - struct list_head node; - void __iomem *chan_reg; - void __iomem *dmars; - unsigned int chcr_offset; - u32 chcr_ie_bit; -}; - -struct sh_dmae_regs { - u32 sar; /* SAR / source address */ - u32 dar; /* DAR / destination address */ - u32 tcr; /* TCR / transfer count */ -}; - -struct sh_dmae_desc { - struct sh_dmae_regs hw; - struct shdma_desc shdma_desc; -}; - -#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, shdma_chan) -#define to_sh_desc(lh) container_of(lh, struct sh_desc, node) -#define tx_to_sh_desc(tx) container_of(tx, struct sh_desc, async_tx) -#define to_sh_dev(chan) container_of(chan->shdma_chan.dma_chan.device,\ - struct sh_dmae_device, shdma_dev.dma_dev) - -#endif /* __DMA_SHDMA_H */ diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c deleted file mode 100644 index 5aafe548ca5f30..00000000000000 --- a/drivers/dma/sh/shdmac.c +++ /dev/null @@ -1,938 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Renesas SuperH DMA Engine support - * - * base is drivers/dma/flsdma.c - * - * Copyright (C) 2011-2012 Guennadi Liakhovetski - * Copyright (C) 2009 Nobuhiro Iwamatsu - * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved. - * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. - * - * - DMA of SuperH does not have Hardware DMA chain mode. - * - MAX DMA size is 16MB. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../dmaengine.h" -#include "shdma.h" - -/* DMA registers */ -#define SAR 0x00 /* Source Address Register */ -#define DAR 0x04 /* Destination Address Register */ -#define TCR 0x08 /* Transfer Count Register */ -#define CHCR 0x0C /* Channel Control Register */ -#define DMAOR 0x40 /* DMA Operation Register */ - -#define TEND 0x18 /* USB-DMAC */ - -#define SH_DMAE_DRV_NAME "sh-dma-engine" - -/* Default MEMCPY transfer size = 2^2 = 4 bytes */ -#define LOG2_DEFAULT_XFER_SIZE 2 -#define SH_DMA_SLAVE_NUMBER 256 -#define SH_DMA_TCR_MAX (16 * 1024 * 1024 - 1) - -/* - * Used for write-side mutual exclusion for the global device list, - * read-side synchronization by way of RCU, and per-controller data. - */ -static DEFINE_SPINLOCK(sh_dmae_lock); -static LIST_HEAD(sh_dmae_devices); - -/* - * Different DMAC implementations provide different ways to clear DMA channels: - * (1) none - no CHCLR registers are available - * (2) one CHCLR register per channel - 0 has to be written to it to clear - * channel buffers - * (3) one CHCLR per several channels - 1 has to be written to the bit, - * corresponding to the specific channel to reset it - */ -static void channel_clear(struct sh_dmae_chan *sh_dc) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_dc); - const struct sh_dmae_channel *chan_pdata = shdev->pdata->channel + - sh_dc->shdma_chan.id; - u32 val = shdev->pdata->chclr_bitwise ? 1 << chan_pdata->chclr_bit : 0; - - __raw_writel(val, shdev->chan_reg + chan_pdata->chclr_offset); -} - -static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) -{ - __raw_writel(data, sh_dc->base + reg); -} - -static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg) -{ - return __raw_readl(sh_dc->base + reg); -} - -static u16 dmaor_read(struct sh_dmae_device *shdev) -{ - void __iomem *addr = shdev->chan_reg + DMAOR; - - if (shdev->pdata->dmaor_is_32bit) - return __raw_readl(addr); - else - return __raw_readw(addr); -} - -static void dmaor_write(struct sh_dmae_device *shdev, u16 data) -{ - void __iomem *addr = shdev->chan_reg + DMAOR; - - if (shdev->pdata->dmaor_is_32bit) - __raw_writel(data, addr); - else - __raw_writew(data, addr); -} - -static void chcr_write(struct sh_dmae_chan *sh_dc, u32 data) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_dc); - - __raw_writel(data, sh_dc->base + shdev->chcr_offset); -} - -static u32 chcr_read(struct sh_dmae_chan *sh_dc) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_dc); - - return __raw_readl(sh_dc->base + shdev->chcr_offset); -} - -/* - * Reset DMA controller - * - * SH7780 has two DMAOR register - */ -static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev) -{ - unsigned short dmaor; - unsigned long flags; - - spin_lock_irqsave(&sh_dmae_lock, flags); - - dmaor = dmaor_read(shdev); - dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME)); - - spin_unlock_irqrestore(&sh_dmae_lock, flags); -} - -static int sh_dmae_rst(struct sh_dmae_device *shdev) -{ - unsigned short dmaor; - unsigned long flags; - - spin_lock_irqsave(&sh_dmae_lock, flags); - - dmaor = dmaor_read(shdev) & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME); - - if (shdev->pdata->chclr_present) { - int i; - for (i = 0; i < shdev->pdata->channel_num; i++) { - struct sh_dmae_chan *sh_chan = shdev->chan[i]; - if (sh_chan) - channel_clear(sh_chan); - } - } - - dmaor_write(shdev, dmaor | shdev->pdata->dmaor_init); - - dmaor = dmaor_read(shdev); - - spin_unlock_irqrestore(&sh_dmae_lock, flags); - - if (dmaor & (DMAOR_AE | DMAOR_NMIF)) { - dev_warn(shdev->shdma_dev.dma_dev.dev, "Can't initialize DMAOR.\n"); - return -EIO; - } - if (shdev->pdata->dmaor_init & ~dmaor) - dev_warn(shdev->shdma_dev.dma_dev.dev, - "DMAOR=0x%x hasn't latched the initial value 0x%x.\n", - dmaor, shdev->pdata->dmaor_init); - return 0; -} - -static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) -{ - u32 chcr = chcr_read(sh_chan); - - if ((chcr & (CHCR_DE | CHCR_TE)) == CHCR_DE) - return true; /* working */ - - return false; /* waiting */ -} - -static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_chan); - const struct sh_dmae_pdata *pdata = shdev->pdata; - int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) | - ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift); - - if (cnt >= pdata->ts_shift_num) - cnt = 0; - - return pdata->ts_shift[cnt]; -} - -static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_chan); - const struct sh_dmae_pdata *pdata = shdev->pdata; - int i; - - for (i = 0; i < pdata->ts_shift_num; i++) - if (pdata->ts_shift[i] == l2size) - break; - - if (i == pdata->ts_shift_num) - i = 0; - - return ((i << pdata->ts_low_shift) & pdata->ts_low_mask) | - ((i << pdata->ts_high_shift) & pdata->ts_high_mask); -} - -static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) -{ - sh_dmae_writel(sh_chan, hw->sar, SAR); - sh_dmae_writel(sh_chan, hw->dar, DAR); - sh_dmae_writel(sh_chan, hw->tcr >> sh_chan->xmit_shift, TCR); -} - -static void dmae_start(struct sh_dmae_chan *sh_chan) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_chan); - u32 chcr = chcr_read(sh_chan); - - if (shdev->pdata->needs_tend_set) - sh_dmae_writel(sh_chan, 0xFFFFFFFF, TEND); - - chcr |= CHCR_DE | shdev->chcr_ie_bit; - chcr_write(sh_chan, chcr & ~CHCR_TE); -} - -static void dmae_init(struct sh_dmae_chan *sh_chan) -{ - /* - * Default configuration for dual address memory-memory transfer. - */ - u32 chcr = DM_INC | SM_INC | RS_AUTO | log2size_to_chcr(sh_chan, - LOG2_DEFAULT_XFER_SIZE); - sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr); - chcr_write(sh_chan, chcr); -} - -static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) -{ - /* If DMA is active, cannot set CHCR. TODO: remove this superfluous check */ - if (dmae_is_busy(sh_chan)) - return -EBUSY; - - sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val); - chcr_write(sh_chan, val); - - return 0; -} - -static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_chan); - const struct sh_dmae_pdata *pdata = shdev->pdata; - const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->shdma_chan.id]; - void __iomem *addr = shdev->dmars; - unsigned int shift = chan_pdata->dmars_bit; - - if (dmae_is_busy(sh_chan)) - return -EBUSY; - - if (pdata->no_dmars) - return 0; - - /* in the case of a missing DMARS resource use first memory window */ - if (!addr) - addr = shdev->chan_reg; - addr += chan_pdata->dmars; - - __raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift), - addr); - - return 0; -} - -static void sh_dmae_start_xfer(struct shdma_chan *schan, - struct shdma_desc *sdesc) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - struct sh_dmae_desc *sh_desc = container_of(sdesc, - struct sh_dmae_desc, shdma_desc); - dev_dbg(sh_chan->shdma_chan.dev, "Queue #%d to %d: %u@%x -> %x\n", - sdesc->async_tx.cookie, sh_chan->shdma_chan.id, - sh_desc->hw.tcr, sh_desc->hw.sar, sh_desc->hw.dar); - /* Get the ld start address from ld_queue */ - dmae_set_reg(sh_chan, &sh_desc->hw); - dmae_start(sh_chan); -} - -static bool sh_dmae_channel_busy(struct shdma_chan *schan) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - return dmae_is_busy(sh_chan); -} - -static void sh_dmae_setup_xfer(struct shdma_chan *schan, - int slave_id) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - - if (slave_id >= 0) { - const struct sh_dmae_slave_config *cfg = - sh_chan->config; - - dmae_set_dmars(sh_chan, cfg->mid_rid); - dmae_set_chcr(sh_chan, cfg->chcr); - } else { - dmae_init(sh_chan); - } -} - -/* - * Find a slave channel configuration from the contoller list by either a slave - * ID in the non-DT case, or by a MID/RID value in the DT case - */ -static const struct sh_dmae_slave_config *dmae_find_slave( - struct sh_dmae_chan *sh_chan, int match) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_chan); - const struct sh_dmae_pdata *pdata = shdev->pdata; - const struct sh_dmae_slave_config *cfg; - int i; - - if (!sh_chan->shdma_chan.dev->of_node) { - if (match >= SH_DMA_SLAVE_NUMBER) - return NULL; - - for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) - if (cfg->slave_id == match) - return cfg; - } else { - for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) - if (cfg->mid_rid == match) { - sh_chan->shdma_chan.slave_id = i; - return cfg; - } - } - - return NULL; -} - -static int sh_dmae_set_slave(struct shdma_chan *schan, - int slave_id, dma_addr_t slave_addr, bool try) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave_id); - if (!cfg) - return -ENXIO; - - if (!try) { - sh_chan->config = cfg; - sh_chan->slave_addr = slave_addr ? : cfg->addr; - } - - return 0; -} - -static void dmae_halt(struct sh_dmae_chan *sh_chan) -{ - struct sh_dmae_device *shdev = to_sh_dev(sh_chan); - u32 chcr = chcr_read(sh_chan); - - chcr &= ~(CHCR_DE | CHCR_TE | shdev->chcr_ie_bit); - chcr_write(sh_chan, chcr); -} - -static int sh_dmae_desc_setup(struct shdma_chan *schan, - struct shdma_desc *sdesc, - dma_addr_t src, dma_addr_t dst, size_t *len) -{ - struct sh_dmae_desc *sh_desc = container_of(sdesc, - struct sh_dmae_desc, shdma_desc); - - if (*len > schan->max_xfer_len) - *len = schan->max_xfer_len; - - sh_desc->hw.sar = src; - sh_desc->hw.dar = dst; - sh_desc->hw.tcr = *len; - - return 0; -} - -static void sh_dmae_halt(struct shdma_chan *schan) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - dmae_halt(sh_chan); -} - -static bool sh_dmae_chan_irq(struct shdma_chan *schan, int irq) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - - if (!(chcr_read(sh_chan) & CHCR_TE)) - return false; - - /* DMA stop */ - dmae_halt(sh_chan); - - return true; -} - -static size_t sh_dmae_get_partial(struct shdma_chan *schan, - struct shdma_desc *sdesc) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, - shdma_chan); - struct sh_dmae_desc *sh_desc = container_of(sdesc, - struct sh_dmae_desc, shdma_desc); - return sh_desc->hw.tcr - - (sh_dmae_readl(sh_chan, TCR) << sh_chan->xmit_shift); -} - -/* Called from error IRQ or NMI */ -static bool sh_dmae_reset(struct sh_dmae_device *shdev) -{ - bool ret; - - /* halt the dma controller */ - sh_dmae_ctl_stop(shdev); - - /* We cannot detect, which channel caused the error, have to reset all */ - ret = shdma_reset(&shdev->shdma_dev); - - sh_dmae_rst(shdev); - - return ret; -} - -static irqreturn_t sh_dmae_err(int irq, void *data) -{ - struct sh_dmae_device *shdev = data; - - if (!(dmaor_read(shdev) & DMAOR_AE)) - return IRQ_NONE; - - sh_dmae_reset(shdev); - return IRQ_HANDLED; -} - -static bool sh_dmae_desc_completed(struct shdma_chan *schan, - struct shdma_desc *sdesc) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, - struct sh_dmae_chan, shdma_chan); - struct sh_dmae_desc *sh_desc = container_of(sdesc, - struct sh_dmae_desc, shdma_desc); - u32 sar_buf = sh_dmae_readl(sh_chan, SAR); - u32 dar_buf = sh_dmae_readl(sh_chan, DAR); - - return (sdesc->direction == DMA_DEV_TO_MEM && - (sh_desc->hw.dar + sh_desc->hw.tcr) == dar_buf) || - (sdesc->direction != DMA_DEV_TO_MEM && - (sh_desc->hw.sar + sh_desc->hw.tcr) == sar_buf); -} - -static bool sh_dmae_nmi_notify(struct sh_dmae_device *shdev) -{ - /* Fast path out if NMIF is not asserted for this controller */ - if ((dmaor_read(shdev) & DMAOR_NMIF) == 0) - return false; - - return sh_dmae_reset(shdev); -} - -static int sh_dmae_nmi_handler(struct notifier_block *self, - unsigned long cmd, void *data) -{ - struct sh_dmae_device *shdev; - int ret = NOTIFY_DONE; - bool triggered; - - /* - * Only concern ourselves with NMI events. - * - * Normally we would check the die chain value, but as this needs - * to be architecture independent, check for NMI context instead. - */ - if (!in_nmi()) - return NOTIFY_DONE; - - rcu_read_lock(); - list_for_each_entry_rcu(shdev, &sh_dmae_devices, node) { - /* - * Only stop if one of the controllers has NMIF asserted, - * we do not want to interfere with regular address error - * handling or NMI events that don't concern the DMACs. - */ - triggered = sh_dmae_nmi_notify(shdev); - if (triggered == true) - ret = NOTIFY_OK; - } - rcu_read_unlock(); - - return ret; -} - -static struct notifier_block sh_dmae_nmi_notifier __read_mostly = { - .notifier_call = sh_dmae_nmi_handler, - - /* Run before NMI debug handler and KGDB */ - .priority = 1, -}; - -static int sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, - int irq, unsigned long flags) -{ - const struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id]; - struct shdma_dev *sdev = &shdev->shdma_dev; - struct platform_device *pdev = to_platform_device(sdev->dma_dev.dev); - struct sh_dmae_chan *sh_chan; - struct shdma_chan *schan; - int err; - - sh_chan = devm_kzalloc(sdev->dma_dev.dev, sizeof(struct sh_dmae_chan), - GFP_KERNEL); - if (!sh_chan) - return -ENOMEM; - - schan = &sh_chan->shdma_chan; - schan->max_xfer_len = SH_DMA_TCR_MAX + 1; - - shdma_chan_probe(sdev, schan, id); - - sh_chan->base = shdev->chan_reg + chan_pdata->offset; - - /* set up channel irq */ - if (pdev->id >= 0) - snprintf(sh_chan->dev_id, sizeof(sh_chan->dev_id), - "sh-dmae%d.%d", pdev->id, id); - else - snprintf(sh_chan->dev_id, sizeof(sh_chan->dev_id), - "sh-dma%d", id); - - err = shdma_request_irq(schan, irq, flags, sh_chan->dev_id); - if (err) { - dev_err(sdev->dma_dev.dev, - "DMA channel %d request_irq error %d\n", - id, err); - goto err_no_irq; - } - - shdev->chan[id] = sh_chan; - return 0; - -err_no_irq: - /* remove from dmaengine device node */ - shdma_chan_remove(schan); - return err; -} - -static void sh_dmae_chan_remove(struct sh_dmae_device *shdev) -{ - struct shdma_chan *schan; - int i; - - shdma_for_each_chan(schan, &shdev->shdma_dev, i) { - BUG_ON(!schan); - - shdma_chan_remove(schan); - } -} - -#ifdef CONFIG_PM -static int sh_dmae_runtime_suspend(struct device *dev) -{ - struct sh_dmae_device *shdev = dev_get_drvdata(dev); - - sh_dmae_ctl_stop(shdev); - return 0; -} - -static int sh_dmae_runtime_resume(struct device *dev) -{ - struct sh_dmae_device *shdev = dev_get_drvdata(dev); - - return sh_dmae_rst(shdev); -} -#endif - -#ifdef CONFIG_PM_SLEEP -static int sh_dmae_suspend(struct device *dev) -{ - struct sh_dmae_device *shdev = dev_get_drvdata(dev); - - sh_dmae_ctl_stop(shdev); - return 0; -} - -static int sh_dmae_resume(struct device *dev) -{ - struct sh_dmae_device *shdev = dev_get_drvdata(dev); - int i, ret; - - ret = sh_dmae_rst(shdev); - if (ret < 0) - dev_err(dev, "Failed to reset!\n"); - - for (i = 0; i < shdev->pdata->channel_num; i++) { - struct sh_dmae_chan *sh_chan = shdev->chan[i]; - - if (!sh_chan->shdma_chan.desc_num) - continue; - - if (sh_chan->shdma_chan.slave_id >= 0) { - const struct sh_dmae_slave_config *cfg = sh_chan->config; - dmae_set_dmars(sh_chan, cfg->mid_rid); - dmae_set_chcr(sh_chan, cfg->chcr); - } else { - dmae_init(sh_chan); - } - } - - return 0; -} -#endif - -static const struct dev_pm_ops sh_dmae_pm = { - SET_SYSTEM_SLEEP_PM_OPS(sh_dmae_suspend, sh_dmae_resume) - SET_RUNTIME_PM_OPS(sh_dmae_runtime_suspend, sh_dmae_runtime_resume, - NULL) -}; - -static dma_addr_t sh_dmae_slave_addr(struct shdma_chan *schan) -{ - struct sh_dmae_chan *sh_chan = container_of(schan, - struct sh_dmae_chan, shdma_chan); - - /* - * Implicit BUG_ON(!sh_chan->config) - * This is an exclusive slave DMA operation, may only be called after a - * successful slave configuration. - */ - return sh_chan->slave_addr; -} - -static struct shdma_desc *sh_dmae_embedded_desc(void *buf, int i) -{ - return &((struct sh_dmae_desc *)buf)[i].shdma_desc; -} - -static const struct shdma_ops sh_dmae_shdma_ops = { - .desc_completed = sh_dmae_desc_completed, - .halt_channel = sh_dmae_halt, - .channel_busy = sh_dmae_channel_busy, - .slave_addr = sh_dmae_slave_addr, - .desc_setup = sh_dmae_desc_setup, - .set_slave = sh_dmae_set_slave, - .setup_xfer = sh_dmae_setup_xfer, - .start_xfer = sh_dmae_start_xfer, - .embedded_desc = sh_dmae_embedded_desc, - .chan_irq = sh_dmae_chan_irq, - .get_partial = sh_dmae_get_partial, -}; - -static int sh_dmae_probe(struct platform_device *pdev) -{ - const enum dma_slave_buswidth widths = - DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES | - DMA_SLAVE_BUSWIDTH_4_BYTES | DMA_SLAVE_BUSWIDTH_8_BYTES | - DMA_SLAVE_BUSWIDTH_16_BYTES | DMA_SLAVE_BUSWIDTH_32_BYTES; - const struct sh_dmae_pdata *pdata; - unsigned long chan_flag[SH_DMAE_MAX_CHANNELS] = {}; - int chan_irq[SH_DMAE_MAX_CHANNELS]; - unsigned long irqflags = 0; - int err, errirq, i, irq_cnt = 0, irqres = 0, irq_cap = 0; - struct sh_dmae_device *shdev; - struct dma_device *dma_dev; - struct resource *chan, *dmars, *errirq_res, *chanirq_res; - - if (pdev->dev.of_node) - pdata = of_device_get_match_data(&pdev->dev); - else - pdata = dev_get_platdata(&pdev->dev); - - /* get platform data */ - if (!pdata || !pdata->channel_num) - return -ENODEV; - - chan = platform_get_resource(pdev, IORESOURCE_MEM, 0); - /* DMARS area is optional */ - dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1); - /* - * IRQ resources: - * 1. there always must be at least one IRQ IO-resource. On SH4 it is - * the error IRQ, in which case it is the only IRQ in this resource: - * start == end. If it is the only IRQ resource, all channels also - * use the same IRQ. - * 2. DMA channel IRQ resources can be specified one per resource or in - * ranges (start != end) - * 3. iff all events (channels and, optionally, error) on this - * controller use the same IRQ, only one IRQ resource can be - * specified, otherwise there must be one IRQ per channel, even if - * some of them are equal - * 4. if all IRQs on this controller are equal or if some specific IRQs - * specify IORESOURCE_IRQ_SHAREABLE in their resources, they will be - * requested with the IRQF_SHARED flag - */ - errirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!chan || !errirq_res) - return -ENODEV; - - shdev = devm_kzalloc(&pdev->dev, sizeof(struct sh_dmae_device), - GFP_KERNEL); - if (!shdev) - return -ENOMEM; - - dma_dev = &shdev->shdma_dev.dma_dev; - - shdev->chan_reg = devm_ioremap_resource(&pdev->dev, chan); - if (IS_ERR(shdev->chan_reg)) - return PTR_ERR(shdev->chan_reg); - if (dmars) { - shdev->dmars = devm_ioremap_resource(&pdev->dev, dmars); - if (IS_ERR(shdev->dmars)) - return PTR_ERR(shdev->dmars); - } - - dma_dev->src_addr_widths = widths; - dma_dev->dst_addr_widths = widths; - dma_dev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); - dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; - - if (!pdata->slave_only) - dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); - if (pdata->slave && pdata->slave_num) - dma_cap_set(DMA_SLAVE, dma_dev->cap_mask); - - /* Default transfer size of 32 bytes requires 32-byte alignment */ - dma_dev->copy_align = LOG2_DEFAULT_XFER_SIZE; - - shdev->shdma_dev.ops = &sh_dmae_shdma_ops; - shdev->shdma_dev.desc_size = sizeof(struct sh_dmae_desc); - err = shdma_init(&pdev->dev, &shdev->shdma_dev, - pdata->channel_num); - if (err < 0) - goto eshdma; - - /* platform data */ - shdev->pdata = pdata; - - if (pdata->chcr_offset) - shdev->chcr_offset = pdata->chcr_offset; - else - shdev->chcr_offset = CHCR; - - if (pdata->chcr_ie_bit) - shdev->chcr_ie_bit = pdata->chcr_ie_bit; - else - shdev->chcr_ie_bit = CHCR_IE; - - platform_set_drvdata(pdev, shdev); - - pm_runtime_enable(&pdev->dev); - err = pm_runtime_get_sync(&pdev->dev); - if (err < 0) - dev_err(&pdev->dev, "%s(): GET = %d\n", __func__, err); - - spin_lock_irq(&sh_dmae_lock); - list_add_tail_rcu(&shdev->node, &sh_dmae_devices); - spin_unlock_irq(&sh_dmae_lock); - - /* reset dma controller - only needed as a test */ - err = sh_dmae_rst(shdev); - if (err) - goto rst_err; - - if (IS_ENABLED(CONFIG_CPU_SH4) || IS_ENABLED(CONFIG_ARCH_RENESAS)) { - chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); - - if (!chanirq_res) - chanirq_res = errirq_res; - else - irqres++; - - if (chanirq_res == errirq_res || - (errirq_res->flags & IORESOURCE_BITS) == IORESOURCE_IRQ_SHAREABLE) - irqflags = IRQF_SHARED; - - errirq = errirq_res->start; - - err = devm_request_irq(&pdev->dev, errirq, sh_dmae_err, - irqflags, "DMAC Address Error", shdev); - if (err) { - dev_err(&pdev->dev, - "DMA failed requesting irq #%d, error %d\n", - errirq, err); - goto eirq_err; - } - } else { - chanirq_res = errirq_res; - } - - if (chanirq_res->start == chanirq_res->end && - !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) { - /* Special case - all multiplexed */ - for (; irq_cnt < pdata->channel_num; irq_cnt++) { - if (irq_cnt < SH_DMAE_MAX_CHANNELS) { - chan_irq[irq_cnt] = chanirq_res->start; - chan_flag[irq_cnt] = IRQF_SHARED; - } else { - irq_cap = 1; - break; - } - } - } else { - do { - for (i = chanirq_res->start; i <= chanirq_res->end; i++) { - if (irq_cnt >= SH_DMAE_MAX_CHANNELS) { - irq_cap = 1; - break; - } - - if ((errirq_res->flags & IORESOURCE_BITS) == - IORESOURCE_IRQ_SHAREABLE) - chan_flag[irq_cnt] = IRQF_SHARED; - else - chan_flag[irq_cnt] = 0; - dev_dbg(&pdev->dev, - "Found IRQ %d for channel %d\n", - i, irq_cnt); - chan_irq[irq_cnt++] = i; - } - - if (irq_cnt >= SH_DMAE_MAX_CHANNELS) - break; - - chanirq_res = platform_get_resource(pdev, - IORESOURCE_IRQ, ++irqres); - } while (irq_cnt < pdata->channel_num && chanirq_res); - } - - /* Create DMA Channel */ - for (i = 0; i < irq_cnt; i++) { - err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]); - if (err) - goto chan_probe_err; - } - - if (irq_cap) - dev_notice(&pdev->dev, "Attempting to register %d DMA " - "channels when a maximum of %d are supported.\n", - pdata->channel_num, SH_DMAE_MAX_CHANNELS); - - pm_runtime_put(&pdev->dev); - - err = dma_async_device_register(&shdev->shdma_dev.dma_dev); - if (err < 0) - goto edmadevreg; - - return err; - -edmadevreg: - pm_runtime_get(&pdev->dev); - -chan_probe_err: - sh_dmae_chan_remove(shdev); - -eirq_err: -rst_err: - spin_lock_irq(&sh_dmae_lock); - list_del_rcu(&shdev->node); - spin_unlock_irq(&sh_dmae_lock); - - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - - shdma_cleanup(&shdev->shdma_dev); -eshdma: - synchronize_rcu(); - - return err; -} - -static int sh_dmae_remove(struct platform_device *pdev) -{ - struct sh_dmae_device *shdev = platform_get_drvdata(pdev); - struct dma_device *dma_dev = &shdev->shdma_dev.dma_dev; - - dma_async_device_unregister(dma_dev); - - spin_lock_irq(&sh_dmae_lock); - list_del_rcu(&shdev->node); - spin_unlock_irq(&sh_dmae_lock); - - pm_runtime_disable(&pdev->dev); - - sh_dmae_chan_remove(shdev); - shdma_cleanup(&shdev->shdma_dev); - - synchronize_rcu(); - - return 0; -} - -static struct platform_driver sh_dmae_driver = { - .driver = { - .pm = &sh_dmae_pm, - .name = SH_DMAE_DRV_NAME, - }, - .remove = sh_dmae_remove, -}; - -static int __init sh_dmae_init(void) -{ - /* Wire up NMI handling */ - int err = register_die_notifier(&sh_dmae_nmi_notifier); - if (err) - return err; - - return platform_driver_probe(&sh_dmae_driver, sh_dmae_probe); -} -module_init(sh_dmae_init); - -static void __exit sh_dmae_exit(void) -{ - platform_driver_unregister(&sh_dmae_driver); - - unregister_die_notifier(&sh_dmae_nmi_notifier); -} -module_exit(sh_dmae_exit); - -MODULE_AUTHOR("Nobuhiro Iwamatsu "); -MODULE_DESCRIPTION("Renesas SH DMA Engine driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" SH_DMAE_DRV_NAME); diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h index 6dfd05ef5c2d9f..dd32aba344757f 100644 --- a/include/linux/shdma-base.h +++ b/include/linux/shdma-base.h @@ -122,13 +122,9 @@ void shdma_chan_remove(struct shdma_chan *schan); int shdma_init(struct device *dev, struct shdma_dev *sdev, int chan_num); void shdma_cleanup(struct shdma_dev *sdev); -#if IS_ENABLED(CONFIG_SH_DMAE_BASE) -bool shdma_chan_filter(struct dma_chan *chan, void *arg); -#else static inline bool shdma_chan_filter(struct dma_chan *chan, void *arg) { return false; } -#endif #endif From patchwork Fri Jan 13 06:23:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642552 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3630C678DF for ; Fri, 13 Jan 2023 06:28:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241015AbjAMG2J (ORCPT ); Fri, 13 Jan 2023 01:28:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235159AbjAMGZO (ORCPT ); Fri, 13 Jan 2023 01:25:14 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98D161BC80; Thu, 12 Jan 2023 22:24:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Sender:Reply-To:Content-ID:Content-Description; bh=38ZdmqJfgTuYXp252hYJNLrwx/7u8Rttfe81dskbpYQ=; b=Dj8Ylj4feHn2Q8zLgHe5rgnue4 +Vm4CVYWIf5GgWiuDd34sTn24Z9KS8CagJsLTrbaAGo+bdtCyIrisky7SzqaYjkbAz1c+1toHsTAk zERaYr6R0NZ5nfOKzpzl38Jjh5JGvj9SvZker/eCdXizSyP8RqgfDnIniAXtmDVMH7uS77fiAX3MG SMTpMiziU7noj7B6ZdgjWYQQlWq7MWw/9kEYFHlda7dz/cdjMI6+Ambw8HLkOzC8SrnJ51N2nKAWd Tb3WfHSt85OhCsocw3wM+N+0KaffKoBMs+e+RifN/F5Tg3MkBHM7JzPqbG6244GTNfxiRKeL3zNBf l46PQTfg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUE-000lh7-6c; Fri, 13 Jan 2023 06:24:23 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 11/22] mtd/nand: remove sh_flctl Date: Fri, 13 Jan 2023 07:23:28 +0100 Message-Id: <20230113062339.1909087-12-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/mtd/nand/raw/Kconfig | 8 - drivers/mtd/nand/raw/Makefile | 1 - drivers/mtd/nand/raw/sh_flctl.c | 1234 ------------------------------- include/linux/mtd/sh_flctl.h | 180 ----- 4 files changed, 1423 deletions(-) delete mode 100644 drivers/mtd/nand/raw/sh_flctl.c delete mode 100644 include/linux/mtd/sh_flctl.h diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 98ea1c9e65c8ef..20a4988ea418d5 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -284,14 +284,6 @@ config MTD_NAND_MXC This enables the driver for the NAND flash controller on the MXC processors. -config MTD_NAND_SH_FLCTL - tristate "Renesas SuperH FLCTL NAND controller" - depends on SUPERH || COMPILE_TEST - depends on HAS_IOMEM - help - Several Renesas SuperH CPU has FLCTL. This option enables support - for NAND Flash using FLCTL. - config MTD_NAND_DAVINCI tristate "DaVinci/Keystone NAND controller" depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF) || COMPILE_TEST diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index fa1d0012031012..2c6eb25c9d0aae 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o obj-$(CONFIG_MTD_NAND_SLC_LPC32XX) += lpc32xx_slc.o obj-$(CONFIG_MTD_NAND_MLC_LPC32XX) += lpc32xx_mlc.o -obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c deleted file mode 100644 index a278829469d610..00000000000000 --- a/drivers/mtd/nand/raw/sh_flctl.c +++ /dev/null @@ -1,1234 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * SuperH FLCTL nand controller - * - * Copyright (c) 2008 Renesas Solutions Corp. - * Copyright (c) 2008 Atom Create Engineering Co., Ltd. - * - * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static int flctl_4secc_ooblayout_sp_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - - if (section) - return -ERANGE; - - oobregion->offset = 0; - oobregion->length = chip->ecc.bytes; - - return 0; -} - -static int flctl_4secc_ooblayout_sp_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - if (section) - return -ERANGE; - - oobregion->offset = 12; - oobregion->length = 4; - - return 0; -} - -static const struct mtd_ooblayout_ops flctl_4secc_oob_smallpage_ops = { - .ecc = flctl_4secc_ooblayout_sp_ecc, - .free = flctl_4secc_ooblayout_sp_free, -}; - -static int flctl_4secc_ooblayout_lp_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - - if (section >= chip->ecc.steps) - return -ERANGE; - - oobregion->offset = (section * 16) + 6; - oobregion->length = chip->ecc.bytes; - - return 0; -} - -static int flctl_4secc_ooblayout_lp_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - - if (section >= chip->ecc.steps) - return -ERANGE; - - oobregion->offset = section * 16; - oobregion->length = 6; - - if (!section) { - oobregion->offset += 2; - oobregion->length -= 2; - } - - return 0; -} - -static const struct mtd_ooblayout_ops flctl_4secc_oob_largepage_ops = { - .ecc = flctl_4secc_ooblayout_lp_ecc, - .free = flctl_4secc_ooblayout_lp_free, -}; - -static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; - -static struct nand_bbt_descr flctl_4secc_smallpage = { - .offs = 11, - .len = 1, - .pattern = scan_ff_pattern, -}; - -static struct nand_bbt_descr flctl_4secc_largepage = { - .offs = 0, - .len = 2, - .pattern = scan_ff_pattern, -}; - -static void empty_fifo(struct sh_flctl *flctl) -{ - writel(flctl->flintdmacr_base | AC1CLR | AC0CLR, FLINTDMACR(flctl)); - writel(flctl->flintdmacr_base, FLINTDMACR(flctl)); -} - -static void start_translation(struct sh_flctl *flctl) -{ - writeb(TRSTRT, FLTRCR(flctl)); -} - -static void timeout_error(struct sh_flctl *flctl, const char *str) -{ - dev_err(&flctl->pdev->dev, "Timeout occurred in %s\n", str); -} - -static void wait_completion(struct sh_flctl *flctl) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - - while (timeout--) { - if (readb(FLTRCR(flctl)) & TREND) { - writeb(0x0, FLTRCR(flctl)); - return; - } - udelay(1); - } - - timeout_error(flctl, __func__); - writeb(0x0, FLTRCR(flctl)); -} - -static void flctl_dma_complete(void *param) -{ - struct sh_flctl *flctl = param; - - complete(&flctl->dma_complete); -} - -static void flctl_release_dma(struct sh_flctl *flctl) -{ - if (flctl->chan_fifo0_rx) { - dma_release_channel(flctl->chan_fifo0_rx); - flctl->chan_fifo0_rx = NULL; - } - if (flctl->chan_fifo0_tx) { - dma_release_channel(flctl->chan_fifo0_tx); - flctl->chan_fifo0_tx = NULL; - } -} - -static void flctl_setup_dma(struct sh_flctl *flctl) -{ - dma_cap_mask_t mask; - struct dma_slave_config cfg; - struct platform_device *pdev = flctl->pdev; - struct sh_flctl_platform_data *pdata = dev_get_platdata(&pdev->dev); - int ret; - - if (!pdata) - return; - - if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0) - return; - - /* We can only either use DMA for both Tx and Rx or not use it at all */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter, - (void *)(uintptr_t)pdata->slave_id_fifo0_tx); - dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__, - flctl->chan_fifo0_tx); - - if (!flctl->chan_fifo0_tx) - return; - - memset(&cfg, 0, sizeof(cfg)); - cfg.direction = DMA_MEM_TO_DEV; - cfg.dst_addr = flctl->fifo; - cfg.src_addr = 0; - ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); - if (ret < 0) - goto err; - - flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter, - (void *)(uintptr_t)pdata->slave_id_fifo0_rx); - dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__, - flctl->chan_fifo0_rx); - - if (!flctl->chan_fifo0_rx) - goto err; - - cfg.direction = DMA_DEV_TO_MEM; - cfg.dst_addr = 0; - cfg.src_addr = flctl->fifo; - ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); - if (ret < 0) - goto err; - - init_completion(&flctl->dma_complete); - - return; - -err: - flctl_release_dma(flctl); -} - -static void set_addr(struct mtd_info *mtd, int column, int page_addr) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint32_t addr = 0; - - if (column == -1) { - addr = page_addr; /* ERASE1 */ - } else if (page_addr != -1) { - /* SEQIN, READ0, etc.. */ - if (flctl->chip.options & NAND_BUSWIDTH_16) - column >>= 1; - if (flctl->page_size) { - addr = column & 0x0FFF; - addr |= (page_addr & 0xff) << 16; - addr |= ((page_addr >> 8) & 0xff) << 24; - /* big than 128MB */ - if (flctl->rw_ADRCNT == ADRCNT2_E) { - uint32_t addr2; - addr2 = (page_addr >> 16) & 0xff; - writel(addr2, FLADR2(flctl)); - } - } else { - addr = column; - addr |= (page_addr & 0xff) << 8; - addr |= ((page_addr >> 8) & 0xff) << 16; - addr |= ((page_addr >> 16) & 0xff) << 24; - } - } - writel(addr, FLADR(flctl)); -} - -static void wait_rfifo_ready(struct sh_flctl *flctl) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - - while (timeout--) { - uint32_t val; - /* check FIFO */ - val = readl(FLDTCNTR(flctl)) >> 16; - if (val & 0xFF) - return; - udelay(1); - } - timeout_error(flctl, __func__); -} - -static void wait_wfifo_ready(struct sh_flctl *flctl) -{ - uint32_t len, timeout = LOOP_TIMEOUT_MAX; - - while (timeout--) { - /* check FIFO */ - len = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF; - if (len >= 4) - return; - udelay(1); - } - timeout_error(flctl, __func__); -} - -static enum flctl_ecc_res_t wait_recfifo_ready - (struct sh_flctl *flctl, int sector_number) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - void __iomem *ecc_reg[4]; - int i; - int state = FL_SUCCESS; - uint32_t data, size; - - /* - * First this loops checks in FLDTCNTR if we are ready to read out the - * oob data. This is the case if either all went fine without errors or - * if the bottom part of the loop corrected the errors or marked them as - * uncorrectable and the controller is given time to push the data into - * the FIFO. - */ - while (timeout--) { - /* check if all is ok and we can read out the OOB */ - size = readl(FLDTCNTR(flctl)) >> 24; - if ((size & 0xFF) == 4) - return state; - - /* check if a correction code has been calculated */ - if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) { - /* - * either we wait for the fifo to be filled or a - * correction pattern is being generated - */ - udelay(1); - continue; - } - - /* check for an uncorrectable error */ - if (readl(FL4ECCCR(flctl)) & _4ECCFA) { - /* check if we face a non-empty page */ - for (i = 0; i < 512; i++) { - if (flctl->done_buff[i] != 0xff) { - state = FL_ERROR; /* can't correct */ - break; - } - } - - if (state == FL_SUCCESS) - dev_dbg(&flctl->pdev->dev, - "reading empty sector %d, ecc error ignored\n", - sector_number); - - writel(0, FL4ECCCR(flctl)); - continue; - } - - /* start error correction */ - ecc_reg[0] = FL4ECCRESULT0(flctl); - ecc_reg[1] = FL4ECCRESULT1(flctl); - ecc_reg[2] = FL4ECCRESULT2(flctl); - ecc_reg[3] = FL4ECCRESULT3(flctl); - - for (i = 0; i < 3; i++) { - uint8_t org; - unsigned int index; - - data = readl(ecc_reg[i]); - - if (flctl->page_size) - index = (512 * sector_number) + - (data >> 16); - else - index = data >> 16; - - org = flctl->done_buff[index]; - flctl->done_buff[index] = org ^ (data & 0xFF); - } - state = FL_REPAIRABLE; - writel(0, FL4ECCCR(flctl)); - } - - timeout_error(flctl, __func__); - return FL_TIMEOUT; /* timeout */ -} - -static void wait_wecfifo_ready(struct sh_flctl *flctl) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - uint32_t len; - - while (timeout--) { - /* check FLECFIFO */ - len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF; - if (len >= 4) - return; - udelay(1); - } - timeout_error(flctl, __func__); -} - -static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, - int len, enum dma_data_direction dir) -{ - struct dma_async_tx_descriptor *desc = NULL; - struct dma_chan *chan; - enum dma_transfer_direction tr_dir; - dma_addr_t dma_addr; - dma_cookie_t cookie; - uint32_t reg; - int ret = 0; - unsigned long time_left; - - if (dir == DMA_FROM_DEVICE) { - chan = flctl->chan_fifo0_rx; - tr_dir = DMA_DEV_TO_MEM; - } else { - chan = flctl->chan_fifo0_tx; - tr_dir = DMA_MEM_TO_DEV; - } - - dma_addr = dma_map_single(chan->device->dev, buf, len, dir); - - if (!dma_mapping_error(chan->device->dev, dma_addr)) - desc = dmaengine_prep_slave_single(chan, dma_addr, len, - tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - - if (desc) { - reg = readl(FLINTDMACR(flctl)); - reg |= DREQ0EN; - writel(reg, FLINTDMACR(flctl)); - - desc->callback = flctl_dma_complete; - desc->callback_param = flctl; - cookie = dmaengine_submit(desc); - if (dma_submit_error(cookie)) { - ret = dma_submit_error(cookie); - dev_warn(&flctl->pdev->dev, - "DMA submit failed, falling back to PIO\n"); - goto out; - } - - dma_async_issue_pending(chan); - } else { - /* DMA failed, fall back to PIO */ - flctl_release_dma(flctl); - dev_warn(&flctl->pdev->dev, - "DMA failed, falling back to PIO\n"); - ret = -EIO; - goto out; - } - - time_left = - wait_for_completion_timeout(&flctl->dma_complete, - msecs_to_jiffies(3000)); - - if (time_left == 0) { - dmaengine_terminate_all(chan); - dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); - ret = -ETIMEDOUT; - } - -out: - reg = readl(FLINTDMACR(flctl)); - reg &= ~DREQ0EN; - writel(reg, FLINTDMACR(flctl)); - - dma_unmap_single(chan->device->dev, dma_addr, len, dir); - - /* ret == 0 is success */ - return ret; -} - -static void read_datareg(struct sh_flctl *flctl, int offset) -{ - unsigned long data; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - wait_completion(flctl); - - data = readl(FLDATAR(flctl)); - *buf = le32_to_cpu(data); -} - -static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset) -{ - int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - len_4align = (rlen + 3) / 4; - - /* initiate DMA transfer */ - if (flctl->chan_fifo0_rx && rlen >= 32 && - !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE)) - goto convert; /* DMA success */ - - /* do polling transfer */ - for (i = 0; i < len_4align; i++) { - wait_rfifo_ready(flctl); - buf[i] = readl(FLDTFIFO(flctl)); - } - -convert: - for (i = 0; i < len_4align; i++) - buf[i] = be32_to_cpu(buf[i]); -} - -static enum flctl_ecc_res_t read_ecfiforeg - (struct sh_flctl *flctl, uint8_t *buff, int sector) -{ - int i; - enum flctl_ecc_res_t res; - unsigned long *ecc_buf = (unsigned long *)buff; - - res = wait_recfifo_ready(flctl , sector); - - if (res != FL_ERROR) { - for (i = 0; i < 4; i++) { - ecc_buf[i] = readl(FLECFIFO(flctl)); - ecc_buf[i] = be32_to_cpu(ecc_buf[i]); - } - } - - return res; -} - -static void write_fiforeg(struct sh_flctl *flctl, int rlen, - unsigned int offset) -{ - int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - len_4align = (rlen + 3) / 4; - for (i = 0; i < len_4align; i++) { - wait_wfifo_ready(flctl); - writel(cpu_to_be32(buf[i]), FLDTFIFO(flctl)); - } -} - -static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, - unsigned int offset) -{ - int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - len_4align = (rlen + 3) / 4; - - for (i = 0; i < len_4align; i++) - buf[i] = cpu_to_be32(buf[i]); - - /* initiate DMA transfer */ - if (flctl->chan_fifo0_tx && rlen >= 32 && - !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE)) - return; /* DMA success */ - - /* do polling transfer */ - for (i = 0; i < len_4align; i++) { - wait_wecfifo_ready(flctl); - writel(buf[i], FLECFIFO(flctl)); - } -} - -static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint32_t flcmncr_val = flctl->flcmncr_base & ~SEL_16BIT; - uint32_t flcmdcr_val, addr_len_bytes = 0; - - /* Set SNAND bit if page size is 2048byte */ - if (flctl->page_size) - flcmncr_val |= SNAND_E; - else - flcmncr_val &= ~SNAND_E; - - /* default FLCMDCR val */ - flcmdcr_val = DOCMD1_E | DOADR_E; - - /* Set for FLCMDCR */ - switch (cmd) { - case NAND_CMD_ERASE1: - addr_len_bytes = flctl->erase_ADRCNT; - flcmdcr_val |= DOCMD2_E; - break; - case NAND_CMD_READ0: - case NAND_CMD_READOOB: - case NAND_CMD_RNDOUT: - addr_len_bytes = flctl->rw_ADRCNT; - flcmdcr_val |= CDSRC_E; - if (flctl->chip.options & NAND_BUSWIDTH_16) - flcmncr_val |= SEL_16BIT; - break; - case NAND_CMD_SEQIN: - /* This case is that cmd is READ0 or READ1 or READ00 */ - flcmdcr_val &= ~DOADR_E; /* ONLY execute 1st cmd */ - break; - case NAND_CMD_PAGEPROG: - addr_len_bytes = flctl->rw_ADRCNT; - flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW; - if (flctl->chip.options & NAND_BUSWIDTH_16) - flcmncr_val |= SEL_16BIT; - break; - case NAND_CMD_READID: - flcmncr_val &= ~SNAND_E; - flcmdcr_val |= CDSRC_E; - addr_len_bytes = ADRCNT_1; - break; - case NAND_CMD_STATUS: - case NAND_CMD_RESET: - flcmncr_val &= ~SNAND_E; - flcmdcr_val &= ~(DOADR_E | DOSR_E); - break; - default: - break; - } - - /* Set address bytes parameter */ - flcmdcr_val |= addr_len_bytes; - - /* Now actually write */ - writel(flcmncr_val, FLCMNCR(flctl)); - writel(flcmdcr_val, FLCMDCR(flctl)); - writel(flcmcdr_val, FLCMCDR(flctl)); -} - -static int flctl_read_page_hwecc(struct nand_chip *chip, uint8_t *buf, - int oob_required, int page) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - - nand_read_page_op(chip, page, 0, buf, mtd->writesize); - if (oob_required) - chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize); - return 0; -} - -static int flctl_write_page_hwecc(struct nand_chip *chip, const uint8_t *buf, - int oob_required, int page) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - - nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize); - chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize); - return nand_prog_page_end_op(chip); -} - -static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int sector, page_sectors; - enum flctl_ecc_res_t ecc_result; - - page_sectors = flctl->page_size ? 4 : 1; - - set_cmd_regs(mtd, NAND_CMD_READ0, - (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); - - writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT, - FLCMNCR(flctl)); - writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl)); - writel(page_addr << 2, FLADR(flctl)); - - empty_fifo(flctl); - start_translation(flctl); - - for (sector = 0; sector < page_sectors; sector++) { - read_fiforeg(flctl, 512, 512 * sector); - - ecc_result = read_ecfiforeg(flctl, - &flctl->done_buff[mtd->writesize + 16 * sector], - sector); - - switch (ecc_result) { - case FL_REPAIRABLE: - dev_info(&flctl->pdev->dev, - "applied ecc on page 0x%x", page_addr); - mtd->ecc_stats.corrected++; - break; - case FL_ERROR: - dev_warn(&flctl->pdev->dev, - "page 0x%x contains corrupted data\n", - page_addr); - mtd->ecc_stats.failed++; - break; - default: - ; - } - } - - wait_completion(flctl); - - writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT), - FLCMNCR(flctl)); -} - -static void execmd_read_oob(struct mtd_info *mtd, int page_addr) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int page_sectors = flctl->page_size ? 4 : 1; - int i; - - set_cmd_regs(mtd, NAND_CMD_READ0, - (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); - - empty_fifo(flctl); - - for (i = 0; i < page_sectors; i++) { - set_addr(mtd, (512 + 16) * i + 512 , page_addr); - writel(16, FLDTCNTR(flctl)); - - start_translation(flctl); - read_fiforeg(flctl, 16, 16 * i); - wait_completion(flctl); - } -} - -static void execmd_write_page_sector(struct mtd_info *mtd) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int page_addr = flctl->seqin_page_addr; - int sector, page_sectors; - - page_sectors = flctl->page_size ? 4 : 1; - - set_cmd_regs(mtd, NAND_CMD_PAGEPROG, - (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); - - empty_fifo(flctl); - writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl)); - writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl)); - writel(page_addr << 2, FLADR(flctl)); - start_translation(flctl); - - for (sector = 0; sector < page_sectors; sector++) { - write_fiforeg(flctl, 512, 512 * sector); - write_ec_fiforeg(flctl, 16, mtd->writesize + 16 * sector); - } - - wait_completion(flctl); - writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl)); -} - -static void execmd_write_oob(struct mtd_info *mtd) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int page_addr = flctl->seqin_page_addr; - int sector, page_sectors; - - page_sectors = flctl->page_size ? 4 : 1; - - set_cmd_regs(mtd, NAND_CMD_PAGEPROG, - (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); - - for (sector = 0; sector < page_sectors; sector++) { - empty_fifo(flctl); - set_addr(mtd, sector * 528 + 512, page_addr); - writel(16, FLDTCNTR(flctl)); /* set read size */ - - start_translation(flctl); - write_fiforeg(flctl, 16, 16 * sector); - wait_completion(flctl); - } -} - -static void flctl_cmdfunc(struct nand_chip *chip, unsigned int command, - int column, int page_addr) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint32_t read_cmd = 0; - - pm_runtime_get_sync(&flctl->pdev->dev); - - flctl->read_bytes = 0; - if (command != NAND_CMD_PAGEPROG) - flctl->index = 0; - - switch (command) { - case NAND_CMD_READ1: - case NAND_CMD_READ0: - if (flctl->hwecc) { - /* read page with hwecc */ - execmd_read_page_sector(mtd, page_addr); - break; - } - if (flctl->page_size) - set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) - | command); - else - set_cmd_regs(mtd, command, command); - - set_addr(mtd, 0, page_addr); - - flctl->read_bytes = mtd->writesize + mtd->oobsize; - if (flctl->chip.options & NAND_BUSWIDTH_16) - column >>= 1; - flctl->index += column; - goto read_normal_exit; - - case NAND_CMD_READOOB: - if (flctl->hwecc) { - /* read page with hwecc */ - execmd_read_oob(mtd, page_addr); - break; - } - - if (flctl->page_size) { - set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) - | NAND_CMD_READ0); - set_addr(mtd, mtd->writesize, page_addr); - } else { - set_cmd_regs(mtd, command, command); - set_addr(mtd, 0, page_addr); - } - flctl->read_bytes = mtd->oobsize; - goto read_normal_exit; - - case NAND_CMD_RNDOUT: - if (flctl->hwecc) - break; - - if (flctl->page_size) - set_cmd_regs(mtd, command, (NAND_CMD_RNDOUTSTART << 8) - | command); - else - set_cmd_regs(mtd, command, command); - - set_addr(mtd, column, 0); - - flctl->read_bytes = mtd->writesize + mtd->oobsize - column; - goto read_normal_exit; - - case NAND_CMD_READID: - set_cmd_regs(mtd, command, command); - - /* READID is always performed using an 8-bit bus */ - if (flctl->chip.options & NAND_BUSWIDTH_16) - column <<= 1; - set_addr(mtd, column, 0); - - flctl->read_bytes = 8; - writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - empty_fifo(flctl); - start_translation(flctl); - read_fiforeg(flctl, flctl->read_bytes, 0); - wait_completion(flctl); - break; - - case NAND_CMD_ERASE1: - flctl->erase1_page_addr = page_addr; - break; - - case NAND_CMD_ERASE2: - set_cmd_regs(mtd, NAND_CMD_ERASE1, - (command << 8) | NAND_CMD_ERASE1); - set_addr(mtd, -1, flctl->erase1_page_addr); - start_translation(flctl); - wait_completion(flctl); - break; - - case NAND_CMD_SEQIN: - if (!flctl->page_size) { - /* output read command */ - if (column >= mtd->writesize) { - column -= mtd->writesize; - read_cmd = NAND_CMD_READOOB; - } else if (column < 256) { - read_cmd = NAND_CMD_READ0; - } else { - column -= 256; - read_cmd = NAND_CMD_READ1; - } - } - flctl->seqin_column = column; - flctl->seqin_page_addr = page_addr; - flctl->seqin_read_cmd = read_cmd; - break; - - case NAND_CMD_PAGEPROG: - empty_fifo(flctl); - if (!flctl->page_size) { - set_cmd_regs(mtd, NAND_CMD_SEQIN, - flctl->seqin_read_cmd); - set_addr(mtd, -1, -1); - writel(0, FLDTCNTR(flctl)); /* set 0 size */ - start_translation(flctl); - wait_completion(flctl); - } - if (flctl->hwecc) { - /* write page with hwecc */ - if (flctl->seqin_column == mtd->writesize) - execmd_write_oob(mtd); - else if (!flctl->seqin_column) - execmd_write_page_sector(mtd); - else - pr_err("Invalid address !?\n"); - break; - } - set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN); - set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr); - writel(flctl->index, FLDTCNTR(flctl)); /* set write size */ - start_translation(flctl); - write_fiforeg(flctl, flctl->index, 0); - wait_completion(flctl); - break; - - case NAND_CMD_STATUS: - set_cmd_regs(mtd, command, command); - set_addr(mtd, -1, -1); - - flctl->read_bytes = 1; - writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - start_translation(flctl); - read_datareg(flctl, 0); /* read and end */ - break; - - case NAND_CMD_RESET: - set_cmd_regs(mtd, command, command); - set_addr(mtd, -1, -1); - - writel(0, FLDTCNTR(flctl)); /* set 0 size */ - start_translation(flctl); - wait_completion(flctl); - break; - - default: - break; - } - goto runtime_exit; - -read_normal_exit: - writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - empty_fifo(flctl); - start_translation(flctl); - read_fiforeg(flctl, flctl->read_bytes, 0); - wait_completion(flctl); -runtime_exit: - pm_runtime_put_sync(&flctl->pdev->dev); - return; -} - -static void flctl_select_chip(struct nand_chip *chip, int chipnr) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - int ret; - - switch (chipnr) { - case -1: - flctl->flcmncr_base &= ~CE0_ENABLE; - - pm_runtime_get_sync(&flctl->pdev->dev); - writel(flctl->flcmncr_base, FLCMNCR(flctl)); - - if (flctl->qos_request) { - dev_pm_qos_remove_request(&flctl->pm_qos); - flctl->qos_request = 0; - } - - pm_runtime_put_sync(&flctl->pdev->dev); - break; - case 0: - flctl->flcmncr_base |= CE0_ENABLE; - - if (!flctl->qos_request) { - ret = dev_pm_qos_add_request(&flctl->pdev->dev, - &flctl->pm_qos, - DEV_PM_QOS_RESUME_LATENCY, - 100); - if (ret < 0) - dev_err(&flctl->pdev->dev, - "PM QoS request failed: %d\n", ret); - flctl->qos_request = 1; - } - - if (flctl->holden) { - pm_runtime_get_sync(&flctl->pdev->dev); - writel(HOLDEN, FLHOLDCR(flctl)); - pm_runtime_put_sync(&flctl->pdev->dev); - } - break; - default: - BUG(); - } -} - -static void flctl_write_buf(struct nand_chip *chip, const uint8_t *buf, int len) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - - memcpy(&flctl->done_buff[flctl->index], buf, len); - flctl->index += len; -} - -static uint8_t flctl_read_byte(struct nand_chip *chip) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - uint8_t data; - - data = flctl->done_buff[flctl->index]; - flctl->index++; - return data; -} - -static void flctl_read_buf(struct nand_chip *chip, uint8_t *buf, int len) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - - memcpy(buf, &flctl->done_buff[flctl->index], len); - flctl->index += len; -} - -static int flctl_chip_attach_chip(struct nand_chip *chip) -{ - u64 targetsize = nanddev_target_size(&chip->base); - struct mtd_info *mtd = nand_to_mtd(chip); - struct sh_flctl *flctl = mtd_to_flctl(mtd); - - /* - * NAND_BUSWIDTH_16 may have been set by nand_scan_ident(). - * Add the SEL_16BIT flag in flctl->flcmncr_base. - */ - if (chip->options & NAND_BUSWIDTH_16) - flctl->flcmncr_base |= SEL_16BIT; - - if (mtd->writesize == 512) { - flctl->page_size = 0; - if (targetsize > (32 << 20)) { - /* big than 32MB */ - flctl->rw_ADRCNT = ADRCNT_4; - flctl->erase_ADRCNT = ADRCNT_3; - } else if (targetsize > (2 << 16)) { - /* big than 128KB */ - flctl->rw_ADRCNT = ADRCNT_3; - flctl->erase_ADRCNT = ADRCNT_2; - } else { - flctl->rw_ADRCNT = ADRCNT_2; - flctl->erase_ADRCNT = ADRCNT_1; - } - } else { - flctl->page_size = 1; - if (targetsize > (128 << 20)) { - /* big than 128MB */ - flctl->rw_ADRCNT = ADRCNT2_E; - flctl->erase_ADRCNT = ADRCNT_3; - } else if (targetsize > (8 << 16)) { - /* big than 512KB */ - flctl->rw_ADRCNT = ADRCNT_4; - flctl->erase_ADRCNT = ADRCNT_2; - } else { - flctl->rw_ADRCNT = ADRCNT_3; - flctl->erase_ADRCNT = ADRCNT_1; - } - } - - if (flctl->hwecc) { - if (mtd->writesize == 512) { - mtd_set_ooblayout(mtd, &flctl_4secc_oob_smallpage_ops); - chip->badblock_pattern = &flctl_4secc_smallpage; - } else { - mtd_set_ooblayout(mtd, &flctl_4secc_oob_largepage_ops); - chip->badblock_pattern = &flctl_4secc_largepage; - } - - chip->ecc.size = 512; - chip->ecc.bytes = 10; - chip->ecc.strength = 4; - chip->ecc.read_page = flctl_read_page_hwecc; - chip->ecc.write_page = flctl_write_page_hwecc; - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; - - /* 4 symbols ECC enabled */ - flctl->flcmncr_base |= _4ECCEN; - } else { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - chip->ecc.algo = NAND_ECC_ALGO_HAMMING; - } - - return 0; -} - -static const struct nand_controller_ops flctl_nand_controller_ops = { - .attach_chip = flctl_chip_attach_chip, -}; - -static irqreturn_t flctl_handle_flste(int irq, void *dev_id) -{ - struct sh_flctl *flctl = dev_id; - - dev_err(&flctl->pdev->dev, "flste irq: %x\n", readl(FLINTDMACR(flctl))); - writel(flctl->flintdmacr_base, FLINTDMACR(flctl)); - - return IRQ_HANDLED; -} - -struct flctl_soc_config { - unsigned long flcmncr_val; - unsigned has_hwecc:1; - unsigned use_holden:1; -}; - -static struct flctl_soc_config flctl_sh7372_config = { - .flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL, - .has_hwecc = 1, - .use_holden = 1, -}; - -static const struct of_device_id of_flctl_match[] = { - { .compatible = "renesas,shmobile-flctl-sh7372", - .data = &flctl_sh7372_config }, - {}, -}; -MODULE_DEVICE_TABLE(of, of_flctl_match); - -static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) -{ - const struct flctl_soc_config *config; - struct sh_flctl_platform_data *pdata; - - config = of_device_get_match_data(dev); - if (!config) { - dev_err(dev, "%s: no OF configuration attached\n", __func__); - return NULL; - } - - pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data), - GFP_KERNEL); - if (!pdata) - return NULL; - - /* set SoC specific options */ - pdata->flcmncr_val = config->flcmncr_val; - pdata->has_hwecc = config->has_hwecc; - pdata->use_holden = config->use_holden; - - return pdata; -} - -static int flctl_probe(struct platform_device *pdev) -{ - struct resource *res; - struct sh_flctl *flctl; - struct mtd_info *flctl_mtd; - struct nand_chip *nand; - struct sh_flctl_platform_data *pdata; - int ret; - int irq; - - flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL); - if (!flctl) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - flctl->reg = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(flctl->reg)) - return PTR_ERR(flctl->reg); - flctl->fifo = res->start + 0x24; /* FLDTFIFO */ - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - ret = devm_request_irq(&pdev->dev, irq, flctl_handle_flste, IRQF_SHARED, - "flste", flctl); - if (ret) { - dev_err(&pdev->dev, "request interrupt failed.\n"); - return ret; - } - - if (pdev->dev.of_node) - pdata = flctl_parse_dt(&pdev->dev); - else - pdata = dev_get_platdata(&pdev->dev); - - if (!pdata) { - dev_err(&pdev->dev, "no setup data defined\n"); - return -EINVAL; - } - - platform_set_drvdata(pdev, flctl); - nand = &flctl->chip; - flctl_mtd = nand_to_mtd(nand); - nand_set_flash_node(nand, pdev->dev.of_node); - flctl_mtd->dev.parent = &pdev->dev; - flctl->pdev = pdev; - flctl->hwecc = pdata->has_hwecc; - flctl->holden = pdata->use_holden; - flctl->flcmncr_base = pdata->flcmncr_val; - flctl->flintdmacr_base = flctl->hwecc ? (STERINTE | ECERB) : STERINTE; - - /* Set address of hardware control function */ - /* 20 us command delay time */ - nand->legacy.chip_delay = 20; - - nand->legacy.read_byte = flctl_read_byte; - nand->legacy.write_buf = flctl_write_buf; - nand->legacy.read_buf = flctl_read_buf; - nand->legacy.select_chip = flctl_select_chip; - nand->legacy.cmdfunc = flctl_cmdfunc; - nand->legacy.set_features = nand_get_set_features_notsupp; - nand->legacy.get_features = nand_get_set_features_notsupp; - - if (pdata->flcmncr_val & SEL_16BIT) - nand->options |= NAND_BUSWIDTH_16; - - nand->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; - - pm_runtime_enable(&pdev->dev); - pm_runtime_resume(&pdev->dev); - - flctl_setup_dma(flctl); - - nand->legacy.dummy_controller.ops = &flctl_nand_controller_ops; - ret = nand_scan(nand, 1); - if (ret) - goto err_chip; - - ret = mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); - if (ret) - goto cleanup_nand; - - return 0; - -cleanup_nand: - nand_cleanup(nand); -err_chip: - flctl_release_dma(flctl); - pm_runtime_disable(&pdev->dev); - return ret; -} - -static int flctl_remove(struct platform_device *pdev) -{ - struct sh_flctl *flctl = platform_get_drvdata(pdev); - struct nand_chip *chip = &flctl->chip; - int ret; - - flctl_release_dma(flctl); - ret = mtd_device_unregister(nand_to_mtd(chip)); - WARN_ON(ret); - nand_cleanup(chip); - pm_runtime_disable(&pdev->dev); - - return 0; -} - -static struct platform_driver flctl_driver = { - .remove = flctl_remove, - .driver = { - .name = "sh_flctl", - .of_match_table = of_flctl_match, - }, -}; - -module_platform_driver_probe(flctl_driver, flctl_probe); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Yoshihiro Shimoda"); -MODULE_DESCRIPTION("SuperH FLCTL driver"); -MODULE_ALIAS("platform:sh_flctl"); diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h deleted file mode 100644 index 78fc2d4218c808..00000000000000 --- a/include/linux/mtd/sh_flctl.h +++ /dev/null @@ -1,180 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * SuperH FLCTL nand controller - * - * Copyright © 2008 Renesas Solutions Corp. - */ - -#ifndef __SH_FLCTL_H__ -#define __SH_FLCTL_H__ - -#include -#include -#include -#include -#include - -/* FLCTL registers */ -#define FLCMNCR(f) (f->reg + 0x0) -#define FLCMDCR(f) (f->reg + 0x4) -#define FLCMCDR(f) (f->reg + 0x8) -#define FLADR(f) (f->reg + 0xC) -#define FLADR2(f) (f->reg + 0x3C) -#define FLDATAR(f) (f->reg + 0x10) -#define FLDTCNTR(f) (f->reg + 0x14) -#define FLINTDMACR(f) (f->reg + 0x18) -#define FLBSYTMR(f) (f->reg + 0x1C) -#define FLBSYCNT(f) (f->reg + 0x20) -#define FLDTFIFO(f) (f->reg + 0x24) -#define FLECFIFO(f) (f->reg + 0x28) -#define FLTRCR(f) (f->reg + 0x2C) -#define FLHOLDCR(f) (f->reg + 0x38) -#define FL4ECCRESULT0(f) (f->reg + 0x80) -#define FL4ECCRESULT1(f) (f->reg + 0x84) -#define FL4ECCRESULT2(f) (f->reg + 0x88) -#define FL4ECCRESULT3(f) (f->reg + 0x8C) -#define FL4ECCCR(f) (f->reg + 0x90) -#define FL4ECCCNT(f) (f->reg + 0x94) -#define FLERRADR(f) (f->reg + 0x98) - -/* FLCMNCR control bits */ -#define _4ECCCNTEN (0x1 << 24) -#define _4ECCEN (0x1 << 23) -#define _4ECCCORRECT (0x1 << 22) -#define SHBUSSEL (0x1 << 20) -#define SEL_16BIT (0x1 << 19) -#define SNAND_E (0x1 << 18) /* SNAND (0=512 1=2048)*/ -#define QTSEL_E (0x1 << 17) -#define ENDIAN (0x1 << 16) /* 1 = little endian */ -#define FCKSEL_E (0x1 << 15) -#define ACM_SACCES_MODE (0x01 << 10) -#define NANWF_E (0x1 << 9) -#define SE_D (0x1 << 8) /* Spare area disable */ -#define CE1_ENABLE (0x1 << 4) /* Chip Enable 1 */ -#define CE0_ENABLE (0x1 << 3) /* Chip Enable 0 */ -#define TYPESEL_SET (0x1 << 0) - -/* - * Clock settings using the PULSEx registers from FLCMNCR - * - * Some hardware uses bits called PULSEx instead of FCKSEL_E and QTSEL_E - * to control the clock divider used between the High-Speed Peripheral Clock - * and the FLCTL internal clock. If so, use CLK_8_BIT_xxx for connecting 8 bit - * and CLK_16_BIT_xxx for connecting 16 bit bus bandwith NAND chips. For the 16 - * bit version the divider is seperate for the pulse width of high and low - * signals. - */ -#define PULSE3 (0x1 << 27) -#define PULSE2 (0x1 << 17) -#define PULSE1 (0x1 << 15) -#define PULSE0 (0x1 << 9) -#define CLK_8B_0_5 PULSE1 -#define CLK_8B_1 0x0 -#define CLK_8B_1_5 (PULSE1 | PULSE2) -#define CLK_8B_2 PULSE0 -#define CLK_8B_3 (PULSE0 | PULSE1 | PULSE2) -#define CLK_8B_4 (PULSE0 | PULSE2) -#define CLK_16B_6L_2H PULSE0 -#define CLK_16B_9L_3H (PULSE0 | PULSE1 | PULSE2) -#define CLK_16B_12L_4H (PULSE0 | PULSE2) - -/* FLCMDCR control bits */ -#define ADRCNT2_E (0x1 << 31) /* 5byte address enable */ -#define ADRMD_E (0x1 << 26) /* Sector address access */ -#define CDSRC_E (0x1 << 25) /* Data buffer selection */ -#define DOSR_E (0x1 << 24) /* Status read check */ -#define SELRW (0x1 << 21) /* 0:read 1:write */ -#define DOADR_E (0x1 << 20) /* Address stage execute */ -#define ADRCNT_1 (0x00 << 18) /* Address data bytes: 1byte */ -#define ADRCNT_2 (0x01 << 18) /* Address data bytes: 2byte */ -#define ADRCNT_3 (0x02 << 18) /* Address data bytes: 3byte */ -#define ADRCNT_4 (0x03 << 18) /* Address data bytes: 4byte */ -#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */ -#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */ - -/* FLINTDMACR control bits */ -#define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */ -#define AC1CLR (0x1 << 19) /* ECC FIFO clear */ -#define AC0CLR (0x1 << 18) /* Data FIFO clear */ -#define DREQ0EN (0x1 << 16) /* FLDTFIFODMA Request Enable */ -#define ECERB (0x1 << 9) /* ECC error */ -#define STERB (0x1 << 8) /* Status error */ -#define STERINTE (0x1 << 4) /* Status error enable */ - -/* FLTRCR control bits */ -#define TRSTRT (0x1 << 0) /* translation start */ -#define TREND (0x1 << 1) /* translation end */ - -/* - * FLHOLDCR control bits - * - * HOLDEN: Bus Occupancy Enable (inverted) - * Enable this bit when the external bus might be used in between transfers. - * If not set and the bus gets used by other modules, a deadlock occurs. - */ -#define HOLDEN (0x1 << 0) - -/* FL4ECCCR control bits */ -#define _4ECCFA (0x1 << 2) /* 4 symbols correct fault */ -#define _4ECCEND (0x1 << 1) /* 4 symbols end */ -#define _4ECCEXST (0x1 << 0) /* 4 symbols exist */ - -#define LOOP_TIMEOUT_MAX 0x00010000 - -enum flctl_ecc_res_t { - FL_SUCCESS, - FL_REPAIRABLE, - FL_ERROR, - FL_TIMEOUT -}; - -struct dma_chan; - -struct sh_flctl { - struct nand_chip chip; - struct platform_device *pdev; - struct dev_pm_qos_request pm_qos; - void __iomem *reg; - resource_size_t fifo; - - uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ - int read_bytes; - unsigned int index; - int seqin_column; /* column in SEQIN cmd */ - int seqin_page_addr; /* page_addr in SEQIN cmd */ - uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */ - int erase1_page_addr; /* page_addr in ERASE1 cmd */ - uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */ - uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */ - uint32_t flcmncr_base; /* base value of FLCMNCR */ - uint32_t flintdmacr_base; /* irq enable bits */ - - unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */ - unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ - unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */ - unsigned qos_request:1; /* QoS request to prevent deep power shutdown */ - - /* DMA related objects */ - struct dma_chan *chan_fifo0_rx; - struct dma_chan *chan_fifo0_tx; - struct completion dma_complete; -}; - -struct sh_flctl_platform_data { - struct mtd_partition *parts; - int nr_parts; - unsigned long flcmncr_val; - - unsigned has_hwecc:1; - unsigned use_holden:1; - - unsigned int slave_id_fifo0_tx; - unsigned int slave_id_fifo0_rx; -}; - -static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) -{ - return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip); -} - -#endif /* __SH_FLCTL_H__ */ From patchwork Fri Jan 13 06:23:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642554 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3FC6C61DB3 for ; Fri, 13 Jan 2023 06:28:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240990AbjAMG2F (ORCPT ); Fri, 13 Jan 2023 01:28:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240573AbjAMGZP (ORCPT ); Fri, 13 Jan 2023 01:25:15 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5BE1410073; Thu, 12 Jan 2023 22:24:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=yNX/9/e3mCL8Z9/A5TRWG0UKPW9ZyWcnD51C6LTuRVI=; b=Ylt8A4HngYHMxsdrT3HnhJDlSV iJ170NFOhoE5/jm4B0r2iZEgG/7ENapsBN7EG3eTyLKpN5X9ZYXjsypPqcTfmEHfo+RwMWyPpP/3+ mjrTudLbbjWOokwEpDHR/SYDPQjEdYu2BrhFltpnBqms3qC6BjqFpSVzUExolaX5+7GIWz7XCFYWp EnNcdwUy6QpwLO2RM/m2LT0BcRLf2dwVUO5JUTWY6khIjWo2kMDSALL69dwv9d7JksbiErk0cYjJy F0GEfksn110Oud3Mh6LP7zQRl0CYW85Mx25oaHsuUudRug/Y9kNkATuSeuGsCBnzF27GOv603zDC4 VB09RLNw==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUH-000ljq-PK; Fri, 13 Jan 2023 06:24:26 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 12/22] net/ethernet/8390: remove stnic Date: Fri, 13 Jan 2023 07:23:29 +0100 Message-Id: <20230113062339.1909087-13-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/net/ethernet/8390/Kconfig | 12 -- drivers/net/ethernet/8390/Makefile | 1 - drivers/net/ethernet/8390/stnic.c | 302 ----------------------------- 3 files changed, 315 deletions(-) delete mode 100644 drivers/net/ethernet/8390/stnic.c diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig index eb90de04c88419..a7976743be9ee3 100644 --- a/drivers/net/ethernet/8390/Kconfig +++ b/drivers/net/ethernet/8390/Kconfig @@ -155,18 +155,6 @@ config PCMCIA_PCNET To compile this driver as a module, choose M here: the module will be called pcnet_cs. If unsure, say N. -config STNIC - tristate "National DP83902AV support" - depends on SUPERH - select CRC32 - help - Support for cards based on the National Semiconductor DP83902AV - ST-NIC Serial Network Interface Controller for Twisted Pair. This - is a 10Mbit/sec Ethernet controller. Product overview and specs at - . - - If unsure, say N. - config ULTRA tristate "SMC Ultra support" depends on ISA diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile index 85c83c566ec663..3819a3bb75a1c9 100644 --- a/drivers/net/ethernet/8390/Makefile +++ b/drivers/net/ethernet/8390/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_NE2000) += ne.o 8390p.o obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o -obj-$(CONFIG_STNIC) += stnic.o 8390.o obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o obj-$(CONFIG_WD80x3) += wd.o 8390.o obj-$(CONFIG_XSURF100) += xsurf100.o diff --git a/drivers/net/ethernet/8390/stnic.c b/drivers/net/ethernet/8390/stnic.c deleted file mode 100644 index bd89ca8a92dfbc..00000000000000 --- a/drivers/net/ethernet/8390/stnic.c +++ /dev/null @@ -1,302 +0,0 @@ -/* stnic.c : A SH7750 specific part of driver for NS DP83902A ST-NIC. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999 kaz Kojima - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef CONFIG_SH_STANDARD_BIOS -#include -#endif - -#include "8390.h" - -#define DRV_NAME "stnic" - -#define byte unsigned char -#define half unsigned short -#define word unsigned int -#define vbyte volatile unsigned char -#define vhalf volatile unsigned short -#define vword volatile unsigned int - -#define STNIC_RUN 0x01 /* 1 == Run, 0 == reset. */ - -#define START_PG 0 /* First page of TX buffer */ -#define STOP_PG 128 /* Last page +1 of RX ring */ - -/* Alias */ -#define STNIC_CR E8390_CMD -#define PG0_RSAR0 EN0_RSARLO -#define PG0_RSAR1 EN0_RSARHI -#define PG0_RBCR0 EN0_RCNTLO -#define PG0_RBCR1 EN0_RCNTHI - -#define CR_RRD E8390_RREAD -#define CR_RWR E8390_RWRITE -#define CR_PG0 E8390_PAGE0 -#define CR_STA E8390_START -#define CR_RDMA E8390_NODMA - -/* FIXME! YOU MUST SET YOUR OWN ETHER ADDRESS. */ -static byte stnic_eadr[6] = -{0x00, 0xc0, 0x6e, 0x00, 0x00, 0x07}; - -static struct net_device *stnic_dev; - -static void stnic_reset (struct net_device *dev); -static void stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page); -static void stnic_block_input (struct net_device *dev, int count, - struct sk_buff *skb , int ring_offset); -static void stnic_block_output (struct net_device *dev, int count, - const unsigned char *buf, int start_page); - -static void stnic_init (struct net_device *dev); - -static u32 stnic_msg_enable; - -module_param_named(msg_enable, stnic_msg_enable, uint, 0444); -MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)"); - -/* SH7750 specific read/write io. */ -static inline void -STNIC_DELAY (void) -{ - vword trash; - trash = *(vword *) 0xa0000000; - trash = *(vword *) 0xa0000000; - trash = *(vword *) 0xa0000000; -} - -static inline byte -STNIC_READ (int reg) -{ - byte val; - - val = (*(vhalf *) (PA_83902 + ((reg) << 1)) >> 8) & 0xff; - STNIC_DELAY (); - return val; -} - -static inline void -STNIC_WRITE (int reg, byte val) -{ - *(vhalf *) (PA_83902 + ((reg) << 1)) = ((half) (val) << 8); - STNIC_DELAY (); -} - -static int __init stnic_probe(void) -{ - struct net_device *dev; - struct ei_device *ei_local; - int err; - - /* If we are not running on a SolutionEngine, give up now */ - if (! MACH_SE) - return -ENODEV; - - /* New style probing API */ - dev = alloc_ei_netdev(); - if (!dev) - return -ENOMEM; - -#ifdef CONFIG_SH_STANDARD_BIOS - sh_bios_get_node_addr (stnic_eadr); -#endif - eth_hw_addr_set(dev, stnic_eadr); - - /* Set the base address to point to the NIC, not the "real" base! */ - dev->base_addr = 0x1000; - dev->irq = IRQ_STNIC; - dev->netdev_ops = &ei_netdev_ops; - - /* Snarf the interrupt now. There's no point in waiting since we cannot - share and the board will usually be enabled. */ - err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev); - if (err) { - netdev_emerg(dev, " unable to get IRQ %d.\n", dev->irq); - free_netdev(dev); - return err; - } - - ei_status.name = dev->name; - ei_status.word16 = 1; -#ifdef __LITTLE_ENDIAN__ - ei_status.bigendian = 0; -#else - ei_status.bigendian = 1; -#endif - ei_status.tx_start_page = START_PG; - ei_status.rx_start_page = START_PG + TX_PAGES; - ei_status.stop_page = STOP_PG; - - ei_status.reset_8390 = &stnic_reset; - ei_status.get_8390_hdr = &stnic_get_hdr; - ei_status.block_input = &stnic_block_input; - ei_status.block_output = &stnic_block_output; - - stnic_init (dev); - ei_local = netdev_priv(dev); - ei_local->msg_enable = stnic_msg_enable; - - err = register_netdev(dev); - if (err) { - free_irq(dev->irq, dev); - free_netdev(dev); - return err; - } - stnic_dev = dev; - - netdev_info(dev, "NS ST-NIC 83902A\n"); - - return 0; -} - -static void -stnic_reset (struct net_device *dev) -{ - struct ei_device *ei_local = netdev_priv(dev); - - *(vhalf *) PA_83902_RST = 0; - udelay (5); - netif_warn(ei_local, hw, dev, "8390 reset done (%ld).\n", jiffies); - *(vhalf *) PA_83902_RST = ~0; - udelay (5); -} - -static void -stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr, - int ring_page) -{ - struct ei_device *ei_local = netdev_priv(dev); - - half buf[2]; - - STNIC_WRITE (PG0_RSAR0, 0); - STNIC_WRITE (PG0_RSAR1, ring_page); - STNIC_WRITE (PG0_RBCR0, 4); - STNIC_WRITE (PG0_RBCR1, 0); - STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); - - buf[0] = *(vhalf *) PA_83902_IF; - STNIC_DELAY (); - buf[1] = *(vhalf *) PA_83902_IF; - STNIC_DELAY (); - hdr->next = buf[0] >> 8; - hdr->status = buf[0] & 0xff; -#ifdef __LITTLE_ENDIAN__ - hdr->count = buf[1]; -#else - hdr->count = ((buf[1] >> 8) & 0xff) | (buf[1] << 8); -#endif - - netif_dbg(ei_local, probe, dev, "ring %x status %02x next %02x count %04x.\n", - ring_page, hdr->status, hdr->next, hdr->count); - - STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); -} - -/* Block input and output, similar to the Crynwr packet driver. If you are - porting to a new ethercard look at the packet driver source for hints. - The HP LAN doesn't use shared memory -- we put the packet - out through the "remote DMA" dataport. */ - -static void -stnic_block_input (struct net_device *dev, int length, struct sk_buff *skb, - int offset) -{ - char *buf = skb->data; - half val; - - STNIC_WRITE (PG0_RSAR0, offset & 0xff); - STNIC_WRITE (PG0_RSAR1, offset >> 8); - STNIC_WRITE (PG0_RBCR0, length & 0xff); - STNIC_WRITE (PG0_RBCR1, length >> 8); - STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); - - if (length & 1) - length++; - - while (length > 0) - { - val = *(vhalf *) PA_83902_IF; -#ifdef __LITTLE_ENDIAN__ - *buf++ = val & 0xff; - *buf++ = val >> 8; -#else - *buf++ = val >> 8; - *buf++ = val & 0xff; -#endif - STNIC_DELAY (); - length -= sizeof (half); - } - - STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); -} - -static void -stnic_block_output (struct net_device *dev, int length, - const unsigned char *buf, int output_page) -{ - STNIC_WRITE (PG0_RBCR0, 1); /* Write non-zero value */ - STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); - STNIC_DELAY (); - - STNIC_WRITE (PG0_RBCR0, length & 0xff); - STNIC_WRITE (PG0_RBCR1, length >> 8); - STNIC_WRITE (PG0_RSAR0, 0); - STNIC_WRITE (PG0_RSAR1, output_page); - STNIC_WRITE (STNIC_CR, CR_RWR | CR_PG0 | CR_STA); - - if (length & 1) - length++; - - while (length > 0) - { -#ifdef __LITTLE_ENDIAN__ - *(vhalf *) PA_83902_IF = ((half) buf[1] << 8) | buf[0]; -#else - *(vhalf *) PA_83902_IF = ((half) buf[0] << 8) | buf[1]; -#endif - STNIC_DELAY (); - buf += sizeof (half); - length -= sizeof (half); - } - - STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); -} - -/* This function resets the STNIC if something screws up. */ -static void -stnic_init (struct net_device *dev) -{ - stnic_reset (dev); - NS8390_init (dev, 0); -} - -static void __exit stnic_cleanup(void) -{ - unregister_netdev(stnic_dev); - free_irq(stnic_dev->irq, stnic_dev); - free_netdev(stnic_dev); -} - -module_init(stnic_probe); -module_exit(stnic_cleanup); -MODULE_LICENSE("GPL"); From patchwork Fri Jan 13 06:23:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642551 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6A44C678D7 for ; Fri, 13 Jan 2023 06:28:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241049AbjAMG2R (ORCPT ); Fri, 13 Jan 2023 01:28:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240712AbjAMG0N (ORCPT ); Fri, 13 Jan 2023 01:26:13 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52AF759FA7; Thu, 12 Jan 2023 22:24:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=4Cn32+DwniiE8Ivc8k8ZYXVlFs6gh/3Rw72W3/GZ4ag=; b=Fve8lBIQorfiJ/FhMD6e1GvYXc rGSPgQTVMyq0dxlP00mFanqHXFeH9t17eVtoz/JRWr+oFTQ0ynGMwYJHt5mfB04KzdaQjOX8Iu9fs nIQCq/R62BjdnWiSBeuBxN7hx5e4sYqYWJU6VIfqx17ddSCZZlu7ubY/3XF9PkfW4XzApYx2Cd9k9 zs2s4D1MofDj9wf4eoTSyb6ybNKwpiGOqGQt9CBguMf+78gDheVOOw6bNmSUU/Blr1SaKqbcwa66y 6cpVyf3vy//XvyjihCdST/c6G+qVI++1b+7abn1kff1W7YyuOYJBrAFCIknOxvbFhCUglhpOxZ9Fo xk7GnO7w==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUW-000lwz-NO; Fri, 13 Jan 2023 06:24:41 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 16/22] spi: remove spi-sh-sci Date: Fri, 13 Jan 2023 07:23:33 +0100 Message-Id: <20230113062339.1909087-17-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/spi/Kconfig | 7 -- drivers/spi/Makefile | 1 - drivers/spi/spi-sh-sci.c | 197 --------------------------------------- 3 files changed, 205 deletions(-) delete mode 100644 drivers/spi/spi-sh-sci.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 7508dcef909c78..76f3bc6f8c81fc 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -882,13 +882,6 @@ config SPI_SH_MSIOF help SPI driver for SuperH and SH Mobile MSIOF blocks. -config SPI_SH_SCI - tristate "SuperH SCI SPI controller" - depends on SUPERH - select SPI_BITBANG - help - SPI driver for SuperH SCI blocks. - config SPI_SH_HSPI tristate "SuperH HSPI controller" depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 342a7eb5181c9b..27d877440c6539 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -118,7 +118,6 @@ obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o -obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o obj-$(CONFIG_SPI_SLAVE_MT27XX) += spi-slave-mt27xx.o obj-$(CONFIG_SPI_SN_F_OSPI) += spi-sn-f-ospi.o diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c deleted file mode 100644 index 8f30531e141867..00000000000000 --- a/drivers/spi/spi-sh-sci.c +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * SH SCI SPI interface - * - * Copyright (c) 2008 Magnus Damm - * - * Based on S3C24XX GPIO based SPI driver, which is: - * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -struct sh_sci_spi { - struct spi_bitbang bitbang; - - void __iomem *membase; - unsigned char val; - struct sh_spi_info *info; - struct platform_device *dev; -}; - -#define SCSPTR(sp) (sp->membase + 0x1c) -#define PIN_SCK (1 << 2) -#define PIN_TXD (1 << 0) -#define PIN_RXD PIN_TXD -#define PIN_INIT ((1 << 1) | (1 << 3) | PIN_SCK | PIN_TXD) - -static inline void setbits(struct sh_sci_spi *sp, int bits, int on) -{ - /* - * We are the only user of SCSPTR so no locking is required. - * Reading bit 2 and 0 in SCSPTR gives pin state as input. - * Writing the same bits sets the output value. - * This makes regular read-modify-write difficult so we - * use sp->val to keep track of the latest register value. - */ - - if (on) - sp->val |= bits; - else - sp->val &= ~bits; - - iowrite8(sp->val, SCSPTR(sp)); -} - -static inline void setsck(struct spi_device *dev, int on) -{ - setbits(spi_master_get_devdata(dev->master), PIN_SCK, on); -} - -static inline void setmosi(struct spi_device *dev, int on) -{ - setbits(spi_master_get_devdata(dev->master), PIN_TXD, on); -} - -static inline u32 getmiso(struct spi_device *dev) -{ - struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); - - return (ioread8(SCSPTR(sp)) & PIN_RXD) ? 1 : 0; -} - -#define spidelay(x) ndelay(x) - -#include "spi-bitbang-txrx.h" - -static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); -} - -static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); -} - -static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); -} - -static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); -} - -static void sh_sci_spi_chipselect(struct spi_device *dev, int value) -{ - struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); - - if (sp->info->chip_select) - (sp->info->chip_select)(sp->info, dev->chip_select, value); -} - -static int sh_sci_spi_probe(struct platform_device *dev) -{ - struct resource *r; - struct spi_master *master; - struct sh_sci_spi *sp; - int ret; - - master = spi_alloc_master(&dev->dev, sizeof(struct sh_sci_spi)); - if (master == NULL) { - dev_err(&dev->dev, "failed to allocate spi master\n"); - ret = -ENOMEM; - goto err0; - } - - sp = spi_master_get_devdata(master); - - platform_set_drvdata(dev, sp); - sp->info = dev_get_platdata(&dev->dev); - if (!sp->info) { - dev_err(&dev->dev, "platform data is missing\n"); - ret = -ENOENT; - goto err1; - } - - /* setup spi bitbang adaptor */ - sp->bitbang.master = master; - sp->bitbang.master->bus_num = sp->info->bus_num; - sp->bitbang.master->num_chipselect = sp->info->num_chipselect; - sp->bitbang.chipselect = sh_sci_spi_chipselect; - - sp->bitbang.txrx_word[SPI_MODE_0] = sh_sci_spi_txrx_mode0; - sp->bitbang.txrx_word[SPI_MODE_1] = sh_sci_spi_txrx_mode1; - sp->bitbang.txrx_word[SPI_MODE_2] = sh_sci_spi_txrx_mode2; - sp->bitbang.txrx_word[SPI_MODE_3] = sh_sci_spi_txrx_mode3; - - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (r == NULL) { - ret = -ENOENT; - goto err1; - } - sp->membase = ioremap(r->start, resource_size(r)); - if (!sp->membase) { - ret = -ENXIO; - goto err1; - } - sp->val = ioread8(SCSPTR(sp)); - setbits(sp, PIN_INIT, 1); - - ret = spi_bitbang_start(&sp->bitbang); - if (!ret) - return 0; - - setbits(sp, PIN_INIT, 0); - iounmap(sp->membase); - err1: - spi_master_put(sp->bitbang.master); - err0: - return ret; -} - -static int sh_sci_spi_remove(struct platform_device *dev) -{ - struct sh_sci_spi *sp = platform_get_drvdata(dev); - - spi_bitbang_stop(&sp->bitbang); - setbits(sp, PIN_INIT, 0); - iounmap(sp->membase); - spi_master_put(sp->bitbang.master); - return 0; -} - -static struct platform_driver sh_sci_spi_drv = { - .probe = sh_sci_spi_probe, - .remove = sh_sci_spi_remove, - .driver = { - .name = "spi_sh_sci", - }, -}; -module_platform_driver(sh_sci_spi_drv); - -MODULE_DESCRIPTION("SH SCI SPI Driver"); -MODULE_AUTHOR("Magnus Damm "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:spi_sh_sci"); From patchwork Fri Jan 13 06:23:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642549 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72348C678D9 for ; Fri, 13 Jan 2023 06:31:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236952AbjAMGbK (ORCPT ); Fri, 13 Jan 2023 01:31:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240759AbjAMG0u (ORCPT ); Fri, 13 Jan 2023 01:26:50 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF2B55BA16; Thu, 12 Jan 2023 22:24:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=UA3Wx2g8+e+Fb1QaXEWK5OP24rFFtFCQfYxWGC/7x1s=; b=NgPhSrF34f2zcVzS0tgAL6SgbE zRtNJPHFDmvbOdI3GA8GgIGbclB1ExF6UYx3/DOow16PdNqNFgArlB6/7DeVG8QXv9klWNTE8z76X RxDxcxbzx1a5/02Maj5eBCzCASpahQtLWA2keIRijYtli8Z/MLfSY9hHS0VU+LPEPmMxQpGIWA7ec 3SfxmuGWVMyYB1NxTK6cbQ94YpmydUsc9sm9uGHn71o4BEIUZobj8AWNqdv6668P1fZZLhJM/SiY9 6mtAfE5wns/6VQmwdJIZFuUB6Mw5tHauSYYU3JYD4h2ywkt/BsuHr9keJXWSSnIiIpSqtpoa6ATWh Wd4bfZDA==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUc-000m1U-Nf; Fri, 13 Jan 2023 06:24:47 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 18/22] usb: remove ehci-sh Date: Fri, 13 Jan 2023 07:23:35 +0100 Message-Id: <20230113062339.1909087-19-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/usb/host/Kconfig | 7 -- drivers/usb/host/ehci-hcd.c | 7 -- drivers/usb/host/ehci-sh.c | 182 ------------------------------------ 3 files changed, 196 deletions(-) delete mode 100644 drivers/usb/host/ehci-sh.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index ca5f657c092cf4..ddd8b798626caf 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -279,13 +279,6 @@ config USB_EHCI_HCD_PPC_OF Enables support for the USB controller present on the PowerPC OpenFirmware platform bus. -config USB_EHCI_SH - bool "EHCI support for SuperH USB controller" - depends on SUPERH || COMPILE_TEST - help - Enables support for the on-chip EHCI controller on the SuperH. - If you use the PCI EHCI controller, this option is not necessary. - config USB_EHCI_EXYNOS tristate "EHCI support for Samsung S5P/Exynos SoC Series" depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index a1930db0da1c3c..e6dfef3492aabe 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1309,10 +1309,6 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_LICENSE ("GPL"); -#ifdef CONFIG_USB_EHCI_SH -#include "ehci-sh.c" -#endif - #ifdef CONFIG_PPC_PS3 #include "ehci-ps3.c" #endif @@ -1330,9 +1326,6 @@ MODULE_LICENSE ("GPL"); #endif static struct platform_driver * const platform_drivers[] = { -#ifdef CONFIG_USB_EHCI_SH - &ehci_hcd_sh_driver, -#endif #ifdef CONFIG_USB_EHCI_HCD_PPC_OF &ehci_hcd_ppc_of_driver, #endif diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c deleted file mode 100644 index c25c51d26f2603..00000000000000 --- a/drivers/usb/host/ehci-sh.c +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * SuperH EHCI host controller driver - * - * Copyright (C) 2010 Paul Mundt - * - * Based on ohci-sh.c and ehci-atmel.c. - */ -#include -#include - -struct ehci_sh_priv { - struct clk *iclk, *fclk; - struct usb_hcd *hcd; -}; - -static int ehci_sh_reset(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - ehci->caps = hcd->regs; - - return ehci_setup(hcd); -} - -static const struct hc_driver ehci_sh_hc_driver = { - .description = hcd_name, - .product_desc = "SuperH EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_USB2 | HCD_DMA | HCD_MEMORY | HCD_BH, - - /* - * basic lifecycle operations - */ - .reset = ehci_sh_reset, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - -#ifdef CONFIG_PM - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif - - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ehci_hcd_sh_probe(struct platform_device *pdev) -{ - struct resource *res; - struct ehci_sh_priv *priv; - struct usb_hcd *hcd; - int irq, ret; - - if (usb_disabled()) - return -ENODEV; - - irq = platform_get_irq(pdev, 0); - if (irq <= 0) { - ret = -ENODEV; - goto fail_create_hcd; - } - - /* initialize hcd */ - hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev, - dev_name(&pdev->dev)); - if (!hcd) { - ret = -ENOMEM; - goto fail_create_hcd; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(hcd->regs)) { - ret = PTR_ERR(hcd->regs); - goto fail_request_resource; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - priv = devm_kzalloc(&pdev->dev, sizeof(struct ehci_sh_priv), - GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto fail_request_resource; - } - - /* These are optional, we don't care if they fail */ - priv->fclk = devm_clk_get(&pdev->dev, "usb_fck"); - if (IS_ERR(priv->fclk)) - priv->fclk = NULL; - - priv->iclk = devm_clk_get(&pdev->dev, "usb_ick"); - if (IS_ERR(priv->iclk)) - priv->iclk = NULL; - - clk_enable(priv->fclk); - clk_enable(priv->iclk); - - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret != 0) { - dev_err(&pdev->dev, "Failed to add hcd"); - goto fail_add_hcd; - } - device_wakeup_enable(hcd->self.controller); - - priv->hcd = hcd; - platform_set_drvdata(pdev, priv); - - return ret; - -fail_add_hcd: - clk_disable(priv->iclk); - clk_disable(priv->fclk); - -fail_request_resource: - usb_put_hcd(hcd); -fail_create_hcd: - dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), ret); - - return ret; -} - -static int ehci_hcd_sh_remove(struct platform_device *pdev) -{ - struct ehci_sh_priv *priv = platform_get_drvdata(pdev); - struct usb_hcd *hcd = priv->hcd; - - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - - clk_disable(priv->fclk); - clk_disable(priv->iclk); - - return 0; -} - -static void ehci_hcd_sh_shutdown(struct platform_device *pdev) -{ - struct ehci_sh_priv *priv = platform_get_drvdata(pdev); - struct usb_hcd *hcd = priv->hcd; - - if (hcd->driver->shutdown) - hcd->driver->shutdown(hcd); -} - -static struct platform_driver ehci_hcd_sh_driver = { - .probe = ehci_hcd_sh_probe, - .remove = ehci_hcd_sh_remove, - .shutdown = ehci_hcd_sh_shutdown, - .driver = { - .name = "sh_ehci", - }, -}; - -MODULE_ALIAS("platform:sh_ehci"); From patchwork Fri Jan 13 06:23:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642550 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C490C54EBD for ; Fri, 13 Jan 2023 06:31:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241442AbjAMGbH (ORCPT ); Fri, 13 Jan 2023 01:31:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239506AbjAMG1K (ORCPT ); Fri, 13 Jan 2023 01:27:10 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37D1E6B18C; Thu, 12 Jan 2023 22:25:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=zn2TAaVu38FIU65k7/MT4xLZlbVRoRB8asSaJE0SHvU=; b=fnW6I1OjxCV/+qCsEUVt/I2ltx pVazaxhtTWwOIFpuSgV6S/wrRsGO0a/JL9Td5f60CfSJn6rTXQrpT7rBZgWhpR1xWyE0Qgwb3e5Zy 4xYHJNUH36rYOUlCEJc2GhFeezJZ9AunFCAdE9DOQH7vpp7WH6nP+ijWR7nX8lLuXuyAS3ijRmg7R N/W1AmVs/dORBf3sC4X6YxUxqheUzey81JPGw+OvSRgvvpFrFD097CgP86vfGOsIcx6qaVl9TOX3v LtdFkCrdEDDEoYkoG3xniDxe0zLInwtaWTr/4pr7zm63OFXIpgGRxp+awTDCHrO/CuJ7EvBvDGGdC +Le7Nwsg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUl-000m83-Hp; Fri, 13 Jan 2023 06:24:56 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 21/22] drivers: platform: remove is_sh_early_platform_device Date: Fri, 13 Jan 2023 07:23:38 +0100 Message-Id: <20230113062339.1909087-22-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org This was used as a hack for sh-architecture device initialization, and with sh gone now, only the stub that always returns 0 is left. Signed-off-by: Christoph Hellwig --- drivers/clocksource/sh_cmt.c | 8 ++------ drivers/clocksource/sh_mtu2.c | 8 ++------ drivers/clocksource/sh_tmu.c | 9 ++------- include/linux/platform_device.h | 12 ------------ 4 files changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 7fed3529bbaf82..4f6d7d40c9fcb1 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -1109,10 +1109,8 @@ static int sh_cmt_probe(struct platform_device *pdev) struct sh_cmt_device *cmt = platform_get_drvdata(pdev); int ret; - if (!is_sh_early_platform_device(pdev)) { - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); if (cmt) { dev_info(&pdev->dev, "kept as earlytimer\n"); @@ -1129,8 +1127,6 @@ static int sh_cmt_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); return ret; } - if (is_sh_early_platform_device(pdev)) - return 0; out: if (cmt->has_clockevent || cmt->has_clocksource) diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index e81e978513f80e..97ac2929e424be 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -448,10 +448,8 @@ static int sh_mtu2_probe(struct platform_device *pdev) struct sh_mtu2_device *mtu = platform_get_drvdata(pdev); int ret; - if (!is_sh_early_platform_device(pdev)) { - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); if (mtu) { dev_info(&pdev->dev, "kept as earlytimer\n"); @@ -468,8 +466,6 @@ static int sh_mtu2_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); return ret; } - if (is_sh_early_platform_device(pdev)) - return 0; out: if (mtu->has_clockevent) diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 596e9146ad54e9..940378d38dd523 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -595,10 +595,8 @@ static int sh_tmu_probe(struct platform_device *pdev) struct sh_tmu_device *tmu = platform_get_drvdata(pdev); int ret; - if (!is_sh_early_platform_device(pdev)) { - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); if (tmu) { dev_info(&pdev->dev, "kept as earlytimer\n"); @@ -616,9 +614,6 @@ static int sh_tmu_probe(struct platform_device *pdev) return ret; } - if (is_sh_early_platform_device(pdev)) - return 0; - out: if (tmu->has_clockevent || tmu->has_clocksource) pm_runtime_irq_safe(&pdev->dev); diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index b0d5a253156ece..894939a74dd20f 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -352,18 +352,6 @@ extern int platform_pm_restore(struct device *dev); #define USE_PLATFORM_PM_SLEEP_OPS #endif -#ifndef CONFIG_SUPERH -/* - * REVISIT: This stub is needed for all non-SuperH users of early platform - * drivers. It should go away once we introduce the new platform_device-based - * early driver framework. - */ -static inline int is_sh_early_platform_device(struct platform_device *pdev) -{ - return 0; -} -#endif /* CONFIG_SUPERH */ - /* For now only SuperH uses it */ void early_platform_cleanup(void);