From patchwork Wed Aug 8 05:25:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Katsuhiro Suzuki X-Patchwork-Id: 143608 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp398063ljj; Tue, 7 Aug 2018 22:26:11 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyVSDx91qwlNJCLm2xnJF/GPtU/xaU5UHnbLMvW9RchtYBScbYuBMW1QApIJVFw64AWxftR X-Received: by 2002:a65:60cd:: with SMTP id r13-v6mr1113333pgv.232.1533705971708; Tue, 07 Aug 2018 22:26:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533705971; cv=none; d=google.com; s=arc-20160816; b=h+DA9KBHD3iz7qMgeNtL/Eqqj55ICPZEY1bZg4aPYUgR4ZcS/A9YS3lRhviyOLrhlB 5Y1CCc6nHE9lLForpwlHXIn0RSHZxglda2v/qZExvz/JZohVPVt3J4WfctYbJIaYtMPu xWb/T5m3BUnJhCWW9RYZb2CM2hlroh4yGrcjNbbtvmk924ER0Sx1Nap+nYlXLB25NLS/ g816AynIDhDS5ENZ1PjQTxl02kyvse39mutzqmmp/bGGR3H0JPbzUw6KX2i++umJ17lq i9W591nBcBj611frF4+iHdSavfa/fJGAGJk6wmnmBpxz9wN3C+HpiS5g481uVgwXCWTI HekQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=N9onSDarwBkbZxJwOa89plAO2Jeu5DEqzKQw1k5MNO4=; b=YQclyjjfDqrg9dIQD/UqEcqPVm3XyM9rBuoSpCr0RjhzUp4kjxv3miQmKEfdKW5ICM 9uTS70u/KI6MHcvHRstsme1qhs/2h3+ioTVs8YyfFzAeoqIpqRFXXdH+bkQBPO2rC+Ph kd0qbu69g+BeqS8xh2gh1SoJzLub5247R4P7VXwNJz0/qjmos+3Llev0ntyV9t30C/Tx cV7KmV9qJLdl7kRBTpzVaZBKVFOPEpxBM7hx6QIFYeqbsT6svjpzdJ4ac18uH9YpjdlO edXrmYpZexsBEUpZ6UoagC+VHYKrEJ2HqIZ+bHxvCO02vwn2o0XIT8CbKFjOxGQkuUL6 xmtg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o12-v6si2504855plg.487.2018.08.07.22.26.11; Tue, 07 Aug 2018 22:26:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727121AbeHHHn3 (ORCPT + 31 others); Wed, 8 Aug 2018 03:43:29 -0400 Received: from mx.socionext.com ([202.248.49.38]:4078 "EHLO mx.socionext.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726921AbeHHHn2 (ORCPT ); Wed, 8 Aug 2018 03:43:28 -0400 Received: from unknown (HELO kinkan-ex.css.socionext.com) ([172.31.9.52]) by mx.socionext.com with ESMTP; 08 Aug 2018 14:25:33 +0900 Received: from mail.mfilter.local (m-filter-2 [10.213.24.62]) by kinkan-ex.css.socionext.com (Postfix) with ESMTP id B735E180B37; Wed, 8 Aug 2018 14:25:33 +0900 (JST) Received: from 172.31.9.53 (172.31.9.53) by m-FILTER with ESMTP; Wed, 8 Aug 2018 14:25:33 +0900 Received: from yuzu.css.socionext.com (yuzu [172.31.8.45]) by iyokan.css.socionext.com (Postfix) with ESMTP id 74DF040372; Wed, 8 Aug 2018 14:25:33 +0900 (JST) Received: from aegis.e01.socionext.com (unknown [10.213.134.210]) by yuzu.css.socionext.com (Postfix) with ESMTP id 4F307120415; Wed, 8 Aug 2018 14:25:33 +0900 (JST) From: Katsuhiro Suzuki To: Mauro Carvalho Chehab , linux-media@vger.kernel.org Cc: Masami Hiramatsu , Jassi Brar , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Katsuhiro Suzuki Subject: [PATCH v2 3/7] media: uniphier: add CSS common file of HSC Date: Wed, 8 Aug 2018 14:25:15 +0900 Message-Id: <20180808052519.14528-4-suzuki.katsuhiro@socionext.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180808052519.14528-1-suzuki.katsuhiro@socionext.com> References: <20180808052519.14528-1-suzuki.katsuhiro@socionext.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add CSS (Cross Stream Switch) code for connecting and switching the MPEG2-TS stream path of inner cores of HSC for Socionext UniPhier SoCs. Signed-off-by: Katsuhiro Suzuki --- Changes from v1: - Split from large patches - Fix include lines - Remove redundant conditions --- drivers/media/platform/uniphier/Makefile | 2 +- drivers/media/platform/uniphier/hsc-css.c | 250 ++++++++++++++++++++++ drivers/media/platform/uniphier/hsc-reg.h | 29 +++ drivers/media/platform/uniphier/hsc.h | 17 ++ 4 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/uniphier/hsc-css.c -- 2.18.0 diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile index c3d67a148dbe..59be2edf0c53 100644 --- a/drivers/media/platform/uniphier/Makefile +++ b/drivers/media/platform/uniphier/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -uniphier-dvb-y += hsc-dma.o +uniphier-dvb-y += hsc-dma.o hsc-css.o obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o diff --git a/drivers/media/platform/uniphier/hsc-css.c b/drivers/media/platform/uniphier/hsc-css.c new file mode 100644 index 000000000000..0ab8156b0ffd --- /dev/null +++ b/drivers/media/platform/uniphier/hsc-css.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Socionext UniPhier DVB driver for High-speed Stream Controller (HSC). +// CSS (Cross Stream Switch) connects MPEG2-TS input port and output port. +// +// Copyright (c) 2018 Socionext Inc. + +#include +#include +#include + +#include "hsc.h" +#include "hsc-reg.h" + +int hsc_css_out_to_ts_in(int out) +{ + if (out >= HSC_CSS_OUT_TSI0 && out <= HSC_CSS_OUT_TSI9) + return HSC_TS_IN0 + (out - HSC_CSS_OUT_TSI0); + + return -1; +} + +int hsc_css_out_to_dpll_src(int out) +{ + if (out >= HSC_CSS_OUT_TSI0 && out <= HSC_CSS_OUT_TSI9) + return HSC_DPLL_SRC_TSI0 + (out - HSC_CSS_OUT_TSI0); + + return -1; +} + +static bool css_in_is_valid(struct hsc_chip *chip, int in) +{ + return in < chip->spec->num_css_in; +} + +static bool css_out_is_valid(struct hsc_chip *chip, int out) +{ + return out < chip->spec->num_css_out; +} + +static const struct hsc_spec_css *css_in_get_spec(struct hsc_chip *chip, + int in) +{ + const struct hsc_spec_css *spec = chip->spec->css_in; + + if (!css_in_is_valid(chip, in)) + return NULL; + + return &spec[in]; +} + +static const struct hsc_spec_css *css_out_get_spec(struct hsc_chip *chip, + int out) +{ + const struct hsc_spec_css *spec = chip->spec->css_out; + + if (!css_out_is_valid(chip, out)) + return NULL; + + return &spec[out]; +} + +int hsc_dpll_get_src(struct hsc_chip *chip, int dpll, int *src) +{ + struct regmap *r = chip->regmap; + u32 v; + + if (!src || dpll >= HSC_DPLL_NUM) + return -EINVAL; + + regmap_read(r, CSS_DPCTRL(dpll), &v); + *src = ffs(v & CSS_DPCTRL_DPSEL_MASK) - 1; + + return 0; +} + +/** + * Select source clock of DPLL. + * + * @dpll: ID of DPLL, use one of HSC_DPLL_* + * @src : ID of clock source, use one of HSC_DPLL_SRC_* or HSC_DPLL_SRC_NONE + * to disconnect + */ +int hsc_dpll_set_src(struct hsc_chip *chip, int dpll, int src) +{ + struct regmap *r = chip->regmap; + u32 v = 0; + + if (dpll >= HSC_DPLL_NUM || src >= HSC_DPLL_SRC_NUM) + return -EINVAL; + + if (src != HSC_DPLL_SRC_NONE) + v = 1 << src; + + regmap_write(r, CSS_DPCTRL(dpll), v); + + return 0; +} + +static int hsc_css_get_polarity(struct hsc_chip *chip, + const struct hsc_reg_css_pol *pol, + bool *sync_bit, bool *val_bit, bool *clk_fall) +{ + struct regmap *r = chip->regmap; + u32 v; + + if (!sync_bit || !val_bit || !clk_fall || !pol->valid) + return -EINVAL; + + regmap_read(r, pol->reg, &v); + + *sync_bit = !!(v & BIT(pol->sft_sync)); + *val_bit = !!(v & BIT(pol->sft_val)); + *clk_fall = !!(v & BIT(pol->sft_clk)); + + return 0; +} + +/** + * Setup signal polarity of TS signals. + * + * @sync_bit : true : The sync signal keeps only 1bit period. + * false: The sync signal keeps during 8bits period. + * @valid_bit: true : The valid signal does not keep during 8bits period. + * false: The valid signal keeps during 8bits period. + * @clk_fall : true : Latch the data at falling edge of clock signal. + * false: Latch the data at rising edge of clock signal. + */ +static int hsc_css_set_polarity(struct hsc_chip *chip, + const struct hsc_reg_css_pol *pol, + bool sync_bit, bool val_bit, bool clk_fall) +{ + struct regmap *r = chip->regmap; + u32 m = 0, v = 0; + + if (!pol->valid) + return -EINVAL; + + if (pol->sft_sync != -1) { + m |= BIT(pol->sft_sync); + if (sync_bit) + v |= BIT(pol->sft_sync); + } + + if (pol->sft_val != -1) { + m |= BIT(pol->sft_val); + if (val_bit) + v |= BIT(pol->sft_val); + } + + if (pol->sft_clk != -1) { + m |= BIT(pol->sft_clk); + if (clk_fall) + v |= BIT(pol->sft_clk); + } + + regmap_update_bits(r, pol->reg, m, v); + + return 0; +} + +int hsc_css_in_get_polarity(struct hsc_chip *chip, int in, + bool *sync_bit, bool *val_bit, bool *clk_fall) +{ + const struct hsc_spec_css *speci = css_in_get_spec(chip, in); + + if (!speci) + return -EINVAL; + + return hsc_css_get_polarity(chip, &speci->pol, + sync_bit, val_bit, clk_fall); +} + +int hsc_css_in_set_polarity(struct hsc_chip *chip, int in, + bool sync_bit, bool val_bit, bool clk_fall) +{ + const struct hsc_spec_css *speci = css_in_get_spec(chip, in); + + if (!speci) + return -EINVAL; + + return hsc_css_set_polarity(chip, &speci->pol, + sync_bit, val_bit, clk_fall); +} + +int hsc_css_out_get_polarity(struct hsc_chip *chip, int out, + bool *sync_bit, bool *val_bit, bool *clk_fall) +{ + const struct hsc_spec_css *speco = css_out_get_spec(chip, out); + + if (!speco) + return -EINVAL; + + return hsc_css_get_polarity(chip, &speco->pol, + sync_bit, val_bit, clk_fall); +} + +int hsc_css_out_set_polarity(struct hsc_chip *chip, int out, + bool sync_bit, bool val_bit, bool clk_fall) +{ + const struct hsc_spec_css *speco = css_out_get_spec(chip, out); + + if (!speco) + return -EINVAL; + + return hsc_css_set_polarity(chip, &speco->pol, + sync_bit, val_bit, clk_fall); +} + +int hsc_css_out_get_src(struct hsc_chip *chip, int *tsi, int out, bool *en) +{ + struct regmap *r = chip->regmap; + const struct hsc_spec_css *speco = css_out_get_spec(chip, out); + u32 v; + + if (!tsi || !en || !speco || !speco->sel.valid) + return -EINVAL; + + regmap_read(r, speco->sel.reg, &v); + *tsi = (v & speco->sel.mask) >> speco->sel.sft; + + regmap_read(r, CSS_OUTPUTENABLE, &v); + *en = !!(v & BIT(out)); + + return 0; +} + +/** + * Connect the input port and output port using CSS (Cross Stream Switch). + * + * @in : Input port number, use one of HSC_CSS_IN_*. + * @out : Output port number, use one of HSC_CSS_OUT_*. + * @en : false: Disable this path. + * true : Enable this path. + */ +int hsc_css_out_set_src(struct hsc_chip *chip, int in, int out, bool en) +{ + struct regmap *r = chip->regmap; + const struct hsc_spec_css *speco = css_out_get_spec(chip, out); + + if (!css_in_is_valid(chip, in) || !speco || !speco->sel.valid) + return -EINVAL; + + regmap_update_bits(r, speco->sel.reg, speco->sel.mask, + in << speco->sel.sft); + + regmap_update_bits(r, CSS_OUTPUTENABLE, BIT(out), (en) ? ~0 : 0); + + return 0; +} diff --git a/drivers/media/platform/uniphier/hsc-reg.h b/drivers/media/platform/uniphier/hsc-reg.h index 2d87960c9b97..e5bc87658361 100644 --- a/drivers/media/platform/uniphier/hsc-reg.h +++ b/drivers/media/platform/uniphier/hsc-reg.h @@ -115,4 +115,33 @@ #define CDMBC_CHATPAGED(i, j) (0x3c10 + ((i) - 1) * 0x48 + (j) * 0x10) #define CDMBC_CHATPAGEU(i, j) (0x3c14 + ((i) - 1) * 0x48 + (j) * 0x10) +/* CSS */ +#define CSS_PTSOCONFIG 0x1c00 +#define CSS_PTSISIGNALPOL 0x1c04 +#define CSS_SIGNALPOLCH(i) (0x1c08 + (i) * 0x4) +#define CSS_OUTPUTENABLE 0x1c10 +#define CSS_OUTPUTCTRL(i) (0x1c14 + (i) * 0x4) +#define CSS_STSOCONFIG 0x1c2c +#define CSS_STSOSIGNALPOL 0x1c30 +#define CSS_DMDSIGNALPOL 0x1c34 +#define CSS_PTSOSIGNALPOL 0x1c38 +#define CSS_PF0CONFIG 0x1c3c +#define CSS_PF1CONFIG 0x1c40 +#define CSS_PFINTENABLE 0x1c44 +#define CSS_PFINTSTATUS 0x1c48 +#define CSS_AVOUTPUTCTRL(i) (0x1c4c + (i) * 0x4) +#define CSS_DPCTRL(i) (0x1c54 + (i) * 0x4) +#define CSS_DPCTRL_DPSEL_MASK GENMASK(22, 0) +#define CSS_DPCTRL_DPSEL_PLAY5 BIT(15) +#define CSS_DPCTRL_DPSEL_PLAY4 BIT(14) +#define CSS_DPCTRL_DPSEL_PLAY3 BIT(13) +#define CSS_DPCTRL_DPSEL_PLAY2 BIT(12) +#define CSS_DPCTRL_DPSEL_PLAY1 BIT(11) +#define CSS_DPCTRL_DPSEL_PLAY0 BIT(10) +#define CSS_DPCTRL_DPSEL_TSI4 BIT(4) +#define CSS_DPCTRL_DPSEL_TSI3 BIT(3) +#define CSS_DPCTRL_DPSEL_TSI2 BIT(2) +#define CSS_DPCTRL_DPSEL_TSI1 BIT(1) +#define CSS_DPCTRL_DPSEL_TSI0 BIT(0) + #endif /* DVB_UNIPHIER_HSC_REG_H__ */ diff --git a/drivers/media/platform/uniphier/hsc.h b/drivers/media/platform/uniphier/hsc.h index fddc66df81c7..1cbd17b475bf 100644 --- a/drivers/media/platform/uniphier/hsc.h +++ b/drivers/media/platform/uniphier/hsc.h @@ -329,6 +329,23 @@ struct hsc_conf { int dma_out; }; +/* CSS */ +int hsc_css_out_to_ts_in(int out); +int hsc_css_out_to_dpll_src(int out); + +int hsc_dpll_get_src(struct hsc_chip *chip, int dpll, int *src); +int hsc_dpll_set_src(struct hsc_chip *chip, int dpll, int src); +int hsc_css_in_get_polarity(struct hsc_chip *chip, int in, + bool *sync_bit, bool *val_bit, bool *clk_fall); +int hsc_css_in_set_polarity(struct hsc_chip *chip, int in, + bool sync_bit, bool val_bit, bool clk_fall); +int hsc_css_out_get_polarity(struct hsc_chip *chip, int out, + bool *sync_bit, bool *val_bit, bool *clk_fall); +int hsc_css_out_set_polarity(struct hsc_chip *chip, int out, + bool sync_bit, bool val_bit, bool clk_fall); +int hsc_css_out_get_src(struct hsc_chip *chip, int *in, int out, bool *en); +int hsc_css_out_set_src(struct hsc_chip *chip, int in, int out, bool en); + /* DMA */ u64 hsc_rb_cnt(struct hsc_dma_buf *buf); u64 hsc_rb_cnt_to_end(struct hsc_dma_buf *buf);