Re: [PATCH v5 3/3] ARM: dts: add dts files for xyref5260 board
On 13 March 2014 10:31, Rahul Sharma r.sh.o...@gmail.com wrote: Thanks Pankaj, On 13 March 2014 06:19, Pankaj Dubey pankaj.du...@samsung.com wrote: Hi Rahul, On 03/13/2014 12:16 AM, Rahul Sharma wrote: The patch adds the dts files for xyref5260 board which is based on Exynos5260 Evt0 sample. Signed-off-by: Rahul Sharma rahul.sha...@samsung.com --- arch/arm/boot/dts/Makefile |1 + arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts | 110 +++ 2 files changed, 111 insertions(+) create mode 100644 arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b9d6a8b..5a391bf 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ exynos5250-arndale.dtb \ exynos5250-smdk5250.dtb \ exynos5250-snow.dtb \ + exynos5260-xyref5260-evt0.dtb \ exynos5420-arndale-octa.dtb \ exynos5420-smdk5420.dtb \ exynos5440-sd5v1.dtb \ diff --git a/arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts b/arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts new file mode 100644 index 000..d7d0aeb --- /dev/null +++ b/arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts @@ -0,0 +1,110 @@ +/* + * SAMSUNG XYREF5260 EVT0 board device tree source + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +#include exynos5260.dtsi + +/ { + model = SAMSUNG XYREF5260 EVT0 board based on EXYNOS5260; + compatible = samsung,xyref5260, samsung,exynos5260; + + memory { + reg = 0x2000 0x8000; + }; + + chosen { + bootargs = console=ttySAC2,115200; + }; + + clocks { + fin_pll: xxti { + compatible = fixed-clock; + clock-frequency = 2400; + clock-output-names = fin_pll; + #clock-cells = 0; + }; + + xrtcxti: xrtcxti { + compatible = fixed-clock; + clock-frequency = 32768; + clock-output-names = xrtcxti; + }; clock-cells property is missing here. I have added #clock-cells only for clocks which are supposed to be referred. IMO we don't need it otherwise. + + spdif_extclk: ioclk_spdif_extclk { + compatible = fixed-clock; + clock-frequency = 49152000; + clock-output-names = ioclk_spdif_extclk; + }; ditto. + }; +}; May I know why other phyclocks and ioclks have not been added? Phyclocks should be added in SoC file. Please refer the other patch. Ioclocks have 2 dimensions. 1) A board may or may not have these. But if board doesn't have them, we may end up with orphans in clock tree. 2) Adding them in SoC is not meaningful because rate is board dependent and cannot be mentioned in SoC file. Without rate, probe will not be successful. What I followed here is adding IO clocks which are resulting into orphan clocks. What we can do is to allow the registration of fixed-io-clocks in clock driver which are provided without RATE? If this looks good, I can post the respective patch for clock driver and dt correction. I want to request experts to comment on this. Regards, Rahul Sharma + +pinctrl_0 { + hdmi_hpd_irq: hdmi-hpd-irq { + samsung,pins = gpx3-7; + samsung,pin-function = 0; + samsung,pin-pud = 1; + samsung,pin-drv = 0; + }; +}; + +uart0 { + status = okay; +}; + +uart1 { + status = okay; +}; + +uart2 { + status = okay; +}; + +uart3 { + status = okay; +}; + +mmc_0 { + status = okay; + num-slots = 1; + broken-cd; + bypass-smu; + supports-highspeed; + supports-hs200-mode; /* 200 Mhz */ + card-detect-delay = 200; + samsung,dw-mshc-ciu-div = 3; + samsung,dw-mshc-sdr-timing = 0 4; + samsung,dw-mshc-ddr-timing = 0 2; + pinctrl-names = default; + pinctrl-0 = sd0_rdqs sd0_clk sd0_cmd sd0_bus1 sd0_bus4 sd0_bus8; + + slot@0 { + reg = 0; + bus-width = 8; + }; +}; + +mmc_2 { + status = okay; + num-slots = 1; + supports-highspeed; + card-detect-delay = 200; + samsung,dw-mshc-ciu-div = 3; + samsung,dw-mshc-sdr-timing = 2 3; + samsung,dw-mshc-ddr-timing = 1 2; + pinctrl-names = default; +
[PATCH V2 RE-SEND 0/7] add new Samsung SXGbE driver
Hi all, This is 2nd posting for Samsung SXGbE driver and just re-sending because of line wrapping in previous posting. Changes since v1: - changed name of driver to SXGbE as per Ben's comment - squashed Joe's neatening for many stuff in original patches Byungho An (1): MAINTAINERS: add maintainer for Samsung sxgbe driver Girish K S (2): net: sxgbe: add EEE(Energy Efficient Ethernet) for Samsung sxgbe net: sxgbe: add WOL(Wakeup-On-Lan)support for Samsung sxgbe Siva Reddy (1): net: sxgbe: add basic framework for Samsung 10Gb ethernet driver Vipul Pandya (3): net: sxgbe: add TSO support for Samsung sxgbe net: sxgbe: add Checksum offload support for Samsung sxgbe net: sxgbe: add ethtool related functions support Samsung sxgbe .../devicetree/bindings/net/samsung-sxgbe.txt | 39 + MAINTAINERS|9 + drivers/net/ethernet/Kconfig |1 + drivers/net/ethernet/Makefile |1 + drivers/net/ethernet/samsung/Kconfig |7 + drivers/net/ethernet/samsung/Makefile |4 + drivers/net/ethernet/samsung/sxgbe_common.h| 571 + drivers/net/ethernet/samsung/sxgbe_core.c | 290 +++ drivers/net/ethernet/samsung/sxgbe_desc.c | 515 drivers/net/ethernet/samsung/sxgbe_desc.h | 298 +++ drivers/net/ethernet/samsung/sxgbe_dma.c | 381 +++ drivers/net/ethernet/samsung/sxgbe_dma.h | 51 + drivers/net/ethernet/samsung/sxgbe_ethtool.c | 628 + drivers/net/ethernet/samsung/sxgbe_main.c | 2447 drivers/net/ethernet/samsung/sxgbe_mdio.c | 274 +++ drivers/net/ethernet/samsung/sxgbe_mtl.c | 279 +++ drivers/net/ethernet/samsung/sxgbe_mtl.h | 108 + drivers/net/ethernet/samsung/sxgbe_platform.c | 272 +++ drivers/net/ethernet/samsung/sxgbe_reg.h | 491 drivers/net/ethernet/samsung/sxgbe_xpcs.c | 92 + drivers/net/ethernet/samsung/sxgbe_xpcs.h | 38 + include/linux/sxgbe_platform.h | 54 + 22 files changed, 6850 insertions(+) Thanks, Byungho An -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 RE-SEND 5/7] net: sxgbe: add WOL(Wakeup-On-Lan)support for Samsung sxgbe
From: Girish K S ks.g...@samsung.com This patch adds support for wake up on magic frame arrival. Also remote wake up on all other packets (unicast, multicast broadcast) is supported. Signed-off-by: Girish K S ks.g...@samsung.com Neatening-by: Joe Perches j...@perches.com Signed-off-by: Byungho An bh74...@samsung.com --- drivers/net/ethernet/samsung/sxgbe_common.h | 15 ++ drivers/net/ethernet/samsung/sxgbe_core.c | 29 ++ drivers/net/ethernet/samsung/sxgbe_ethtool.c | 47 drivers/net/ethernet/samsung/sxgbe_main.c | 71 + drivers/net/ethernet/samsung/sxgbe_mtl.c | 43 ++- drivers/net/ethernet/samsung/sxgbe_mtl.h |4 ++ drivers/net/ethernet/samsung/sxgbe_platform.c |4 ++ drivers/net/ethernet/samsung/sxgbe_reg.h |3 ++ 8 files changed, 215 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/samsung/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe_common.h index 68e8ad4..b029181 100644 --- a/drivers/net/ethernet/samsung/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe_common.h @@ -121,9 +121,18 @@ struct sxgbe_mtl_ops; #define RX_ENTRY_LPI_MODE 0x40 #define RX_EXIT_LPI_MODE 0x80 +/* PMT mode bits */ +#define PMT_PWRDWN BIT(0) +#define PMT_MGPKT_EN BIT(1) +#define PMT_RWKPKT_EN BIT(2) +#define PMT_GUCAST_EN BIT(9) + /* EEE-LPI Interrupt status flag */ #define LPI_INT_STATUS BIT(5) +/* PMT Interrupt status */ +#define PMT_INT_STATUS BIT(4) + /* EEE-LPI Default timer values */ #define LPI_LINK_STATUS_TIMER 0x3E8 #define LPI_MAC_WAIT_TIMER 0x00 @@ -225,6 +234,7 @@ struct sxgbe_extra_stats { unsigned long rx_desc_access_err; unsigned long rx_buffer_access_err; unsigned long rx_data_transfer_err; + unsigned long pmt_irq_event_n; /* EEE-LPI stats */ unsigned long tx_lpi_entry_n; @@ -502,6 +512,11 @@ struct sxgbe_priv_data { int eee_enabled; int eee_active; int tx_lpi_timer; + + /* PM-WOL specific members */ + int wolopts; + int wolenabled; + int wol_irq; }; /* Function prototypes */ diff --git a/drivers/net/ethernet/samsung/sxgbe_core.c b/drivers/net/ethernet/samsung/sxgbe_core.c index 5885fd6..334d196 100644 --- a/drivers/net/ethernet/samsung/sxgbe_core.c +++ b/drivers/net/ethernet/samsung/sxgbe_core.c @@ -78,12 +78,41 @@ static int sxgbe_core_host_irq_status(void __iomem *ioaddr, if (unlikely(irq_status LPI_INT_STATUS)) status |= sxgbe_get_lpi_status(ioaddr, irq_status); + if (unlikely(irq_status PMT_INT_STATUS)) { + /* clear the PMT bits 5 and 6 by reading the PMT status reg */ + readl(ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + x-pmt_irq_event_n++; + } + return status; } /* Set power management mode (e.g. magic frame) */ static void sxgbe_core_pmt(void __iomem *ioaddr, unsigned long mode) { + unsigned int pmt = 0; + + if (mode WAKE_MAGIC) { + pr_debug(WOL Magic frame\n); + pmt |= PMT_MGPKT_EN; + } + if (mode WAKE_UCAST) { + pr_debug(WOL on global unicast\n); + pmt |= PMT_GUCAST_EN; + } + if (mode (WAKE_MCAST | WAKE_BCAST)) { + pr_debug(WOL on any other packet\n); + pmt |= PMT_RWKPKT_EN; + } + + writel(pmt, ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + + /* Enable power down bit if any of the requested mode is enabled */ + if (pmt) { + writel(SXGBE_RX_ENABLE, ioaddr + SXGBE_CORE_RX_CONFIG_REG); + pmt |= PMT_PWRDWN; + writel(pmt, ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + } } /* Set/Get Unicast MAC addresses */ diff --git a/drivers/net/ethernet/samsung/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe_ethtool.c index 9083300..89b1450 100644 --- a/drivers/net/ethernet/samsung/sxgbe_ethtool.c +++ b/drivers/net/ethernet/samsung/sxgbe_ethtool.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME : fmt +#include linux/interrupt.h #include linux/kernel.h #include linux/netdevice.h #include linux/phy.h @@ -37,6 +38,7 @@ static const struct sxgbe_stats sxgbe_gstrings_stats[] = { SXGBE_STAT(rx_lpi_entry_n), SXGBE_STAT(rx_lpi_exit_n), SXGBE_STAT(eee_wakeup_error_n), + SXGBE_STAT(pmt_irq_event_n), }; #define SXGBE_STATS_LEN ARRAY_SIZE(sxgbe_gstrings_stats) @@ -80,9 +82,54 @@ static int sxgbe_ethtool_set_eee(struct net_device *dev, return phy_ethtool_set_eee(priv-phydev, edata); } +static void sxgbe_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct sxgbe_priv_data *priv = netdev_priv(dev); + + wol-wolopts = 0; + if (!device_can_wakeup(priv-device)) { + dev_err(priv-device, cannot wakeup device\n); +
[PATCH V2 RE-SEND 3/7] net: sxgbe: add EEE(Energy Efficient Ethernet) for Samsung sxgbe
From: Girish K S ks.g...@samsung.com Added support for the EEE(Energy Efficient Ethernet) in 10G ethernet driver. Signed-off-by: Girish K S ks.g...@samsung.com Neatening-by: Joe Perches j...@perches.com Signed-off-by: Byungho An bh74...@samsung.com --- drivers/net/ethernet/samsung/sxgbe_common.h | 54 + drivers/net/ethernet/samsung/sxgbe_core.c | 86 +- drivers/net/ethernet/samsung/sxgbe_ethtool.c | 47 drivers/net/ethernet/samsung/sxgbe_main.c | 152 - drivers/net/ethernet/samsung/sxgbe_platform.c |4 + drivers/net/ethernet/samsung/sxgbe_reg.h |5 + 6 files changed, 346 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/samsung/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe_common.h index 3f16220..21d8ee6 100644 --- a/drivers/net/ethernet/samsung/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe_common.h @@ -115,6 +115,33 @@ struct sxgbe_mtl_ops; #define RX_PTP_SIGNAL 0x0A #define RX_PTP_RESV_MSG0x0F +/* EEE-LPI mode flags*/ +#define TX_ENTRY_LPI_MODE 0x10 +#define TX_EXIT_LPI_MODE 0x20 +#define RX_ENTRY_LPI_MODE 0x40 +#define RX_EXIT_LPI_MODE 0x80 + +/* EEE-LPI Interrupt status flag */ +#define LPI_INT_STATUS BIT(5) + +/* EEE-LPI Default timer values */ +#define LPI_LINK_STATUS_TIMER 0x3E8 +#define LPI_MAC_WAIT_TIMER 0x00 + +/* EEE-LPI Control and status definitions */ +#define LPI_CTRL_STATUS_TXABIT(19) +#define LPI_CTRL_STATUS_PLSDIS BIT(18) +#define LPI_CTRL_STATUS_PLSBIT(17) +#define LPI_CTRL_STATUS_LPIEN BIT(16) +#define LPI_CTRL_STATUS_TXRSTP BIT(11) +#define LPI_CTRL_STATUS_RXRSTP BIT(10) +#define LPI_CTRL_STATUS_RLPIST BIT(9) +#define LPI_CTRL_STATUS_TLPIST BIT(8) +#define LPI_CTRL_STATUS_RLPIEX BIT(3) +#define LPI_CTRL_STATUS_RLPIEN BIT(2) +#define LPI_CTRL_STATUS_TLPIEX BIT(1) +#define LPI_CTRL_STATUS_TLPIEN BIT(0) + enum dma_irq_status { tx_hard_error = BIT(0), tx_bump_tc = BIT(1), @@ -199,6 +226,13 @@ struct sxgbe_extra_stats { unsigned long rx_buffer_access_err; unsigned long rx_data_transfer_err; + /* EEE-LPI stats */ + unsigned long tx_lpi_entry_n; + unsigned long tx_lpi_exit_n; + unsigned long rx_lpi_entry_n; + unsigned long rx_lpi_exit_n; + unsigned long eee_wakeup_error_n; + /* RX specific */ /* L2 error */ unsigned long rx_code_gmii_err; @@ -306,6 +340,13 @@ struct sxgbe_core_ops { unsigned char feature_index); /* adjust SXGBE speed */ void (*set_speed)(void __iomem *ioaddr, unsigned char speed); + + /* EEE-LPI specific operations */ + void (*set_eee_mode)(void __iomem *ioaddr); + void (*reset_eee_mode)(void __iomem *ioaddr); + void (*set_eee_timer)(void __iomem *ioaddr, const int ls, + const int tw); + void (*set_eee_pls)(void __iomem *ioaddr, const int link); }; const struct sxgbe_core_ops *sxgbe_get_core_ops(void); @@ -367,6 +408,8 @@ struct sxgbe_hw_features { /* IEEE 1588-2008 */ unsigned int atime_stamp; + unsigned int eee; + unsigned int tx_csum_offload; unsigned int rx_csum_offload; unsigned int multi_macaddr; @@ -447,6 +490,14 @@ struct sxgbe_priv_data { u32 adv_ts; int use_riwt; spinlock_t ptp_lock; + + /* EEE-LPI specific members */ + struct timer_list eee_ctrl_timer; + bool tx_path_in_lpi_mode; + int lpi_irq; + int eee_enabled; + int eee_active; + int tx_lpi_timer; }; /* Function prototypes */ @@ -469,4 +520,7 @@ int sxgbe_restore(struct net_device *ndev); const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void); +void sxgbe_disable_eee_mode(struct sxgbe_priv_data * const priv); +bool sxgbe_eee_init(struct sxgbe_priv_data * const priv); + #endif /* __SXGBE_COMMON_H__ */ diff --git a/drivers/net/ethernet/samsung/sxgbe_core.c b/drivers/net/ethernet/samsung/sxgbe_core.c index 17eea58..bf93b16 100644 --- a/drivers/net/ethernet/samsung/sxgbe_core.c +++ b/drivers/net/ethernet/samsung/sxgbe_core.c @@ -47,11 +47,38 @@ static void sxgbe_core_dump_regs(void __iomem *ioaddr) { } +static int sxgbe_get_lpi_status(void __iomem *ioaddr, const u32 irq_status) +{ + int status = 0; + int lpi_status; + + /* Reading this register shall clear all the LPI status bits */ + lpi_status = readl(ioaddr + SXGBE_CORE_LPI_CTRL_STATUS); + + if (lpi_status LPI_CTRL_STATUS_TLPIEN) + status |= TX_ENTRY_LPI_MODE; + if (lpi_status LPI_CTRL_STATUS_TLPIEX) + status |= TX_EXIT_LPI_MODE; + if (lpi_status LPI_CTRL_STATUS_RLPIEN) + status |= RX_ENTRY_LPI_MODE; + if (lpi_status LPI_CTRL_STATUS_RLPIEX) + status |= RX_EXIT_LPI_MODE; + + return status; +} + /* Handle extra events on specific
[PATCH V2 RE-SEND 2/7] net: sxgbe: add TSO support for Samsung sxgbe
From: Vipul Pandya vipul.pan...@samsung.com Enable TSO during initialization for each DMA channels Signed-off-by: Vipul Pandya vipul.pan...@samsung.com Neatening-by: Joe Perches j...@perches.com Signed-off-by: Byungho An bh74...@samsung.com --- drivers/net/ethernet/samsung/sxgbe_desc.c | 47 +++--- drivers/net/ethernet/samsung/sxgbe_desc.h | 17 +-- drivers/net/ethernet/samsung/sxgbe_dma.c | 10 drivers/net/ethernet/samsung/sxgbe_dma.h |2 + drivers/net/ethernet/samsung/sxgbe_main.c | 75 ++--- 5 files changed, 130 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/samsung/sxgbe_desc.c b/drivers/net/ethernet/samsung/sxgbe_desc.c index 9a93553..fa21236 100644 --- a/drivers/net/ethernet/samsung/sxgbe_desc.c +++ b/drivers/net/ethernet/samsung/sxgbe_desc.c @@ -28,6 +28,16 @@ static void sxgbe_init_tx_desc(struct sxgbe_tx_norm_desc *p) p-tdes23.tx_rd_des23.own_bit = 0; } +static void sxgbe_tx_desc_enable_tse(struct sxgbe_tx_norm_desc *p, u8 is_tse, +u32 total_hdr_len, u32 tcp_hdr_len, +u32 tcp_payload_len) +{ + p-tdes23.tx_rd_des23.tse_bit = is_tse; + p-tdes23.tx_rd_des23.buf1_size = total_hdr_len; + p-tdes23.tx_rd_des23.tcp_hdr_len = tcp_hdr_len / 4; + p-tdes23.tx_rd_des23.tx_pkt_len.tcp_payload_len = tcp_payload_len; +} + /* Assign buffer lengths for descriptor */ static void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd, int buf1_len, int pkt_len, int cksum) @@ -102,36 +112,47 @@ static int sxgbe_get_tx_timestamp_status(struct sxgbe_tx_norm_desc *p) } /* TX Context Descripto Specific */ -static void sxgbe_init_tx_ctxtdesc(struct sxgbe_tx_ctxt_desc *p) +static void sxgbe_tx_ctxt_desc_set_ctxt(struct sxgbe_tx_ctxt_desc *p) { p-ctxt_bit = 1; - p-own_bit = 0; } /* Set the owner of TX context descriptor */ -static void sxgbe_set_tx_ctxt_owner(struct sxgbe_tx_ctxt_desc *p) +static void sxgbe_tx_ctxt_desc_set_owner(struct sxgbe_tx_ctxt_desc *p) { p-own_bit = 1; } /* Get the owner of TX context descriptor */ -static int sxgbe_get_tx_ctxt_owner(struct sxgbe_tx_ctxt_desc *p) +static int sxgbe_tx_ctxt_desc_get_owner(struct sxgbe_tx_ctxt_desc *p) { return p-own_bit; } /* Set TX mss in TX context Descriptor */ -static void sxgbe_tx_ctxt_desc_setmss(struct sxgbe_tx_ctxt_desc *p, int mss) +static void sxgbe_tx_ctxt_desc_set_mss(struct sxgbe_tx_ctxt_desc *p, u16 mss) { p-maxseg_size = mss; } /* Get TX mss from TX context Descriptor */ -static int sxgbe_tx_ctxt_desc_getmss(struct sxgbe_tx_ctxt_desc *p) +static int sxgbe_tx_ctxt_desc_get_mss(struct sxgbe_tx_ctxt_desc *p) { return p-maxseg_size; } +/* Set TX tcmssv in TX context Descriptor */ +static void sxgbe_tx_ctxt_desc_set_tcmssv(struct sxgbe_tx_ctxt_desc *p) +{ + p-tcmssv = 1; +} + +/* Reset TX ostc in TX context Descriptor */ +static void sxgbe_tx_ctxt_desc_reset_ostc(struct sxgbe_tx_ctxt_desc *p) +{ + p-ostc = 0; +} + /* Set IVLAN information */ static void sxgbe_tx_ctxt_desc_set_ivlantag(struct sxgbe_tx_ctxt_desc *p, int is_ivlanvalid, int ivlan_tag, @@ -177,13 +198,13 @@ static void sxgbe_tx_ctxt_desc_set_tstamp(struct sxgbe_tx_ctxt_desc *p, } } /* Close TX context descriptor */ -static void sxgbe_close_tx_ctxt_desc(struct sxgbe_tx_ctxt_desc *p) +static void sxgbe_tx_ctxt_desc_close(struct sxgbe_tx_ctxt_desc *p) { p-own_bit = 1; } /* WB status of context descriptor */ -static int sxgbe_get_tx_ctxt_cde(struct sxgbe_tx_ctxt_desc *p) +static int sxgbe_tx_ctxt_desc_get_cde(struct sxgbe_tx_ctxt_desc *p) { return p-ctxt_desc_err; } @@ -432,6 +453,7 @@ static u64 sxgbe_get_rx_timestamp(struct sxgbe_rx_ctxt_desc *p) static const struct sxgbe_desc_ops desc_ops = { .init_tx_desc = sxgbe_init_tx_desc, + .tx_desc_enable_tse = sxgbe_tx_desc_enable_tse, .prepare_tx_desc = sxgbe_prepare_tx_desc, .tx_vlanctl_desc = sxgbe_tx_vlanctl_desc, .set_tx_owner = sxgbe_set_tx_owner, @@ -443,11 +465,20 @@ static const struct sxgbe_desc_ops desc_ops = { .get_tx_len = sxgbe_get_tx_len, .tx_enable_tstamp = sxgbe_tx_enable_tstamp, .get_tx_timestamp_status = sxgbe_get_tx_timestamp_status, + .tx_ctxt_desc_set_ctxt = sxgbe_tx_ctxt_desc_set_ctxt, + .tx_ctxt_desc_set_owner = sxgbe_tx_ctxt_desc_set_owner, + .get_tx_ctxt_owner = sxgbe_tx_ctxt_desc_get_owner, + .tx_ctxt_desc_set_mss = sxgbe_tx_ctxt_desc_set_mss, + .tx_ctxt_desc_get_mss = sxgbe_tx_ctxt_desc_get_mss, + .tx_ctxt_desc_set_tcmssv = sxgbe_tx_ctxt_desc_set_tcmssv, + .tx_ctxt_desc_reset_ostc = sxgbe_tx_ctxt_desc_reset_ostc, .tx_ctxt_desc_set_ivlantag = sxgbe_tx_ctxt_desc_set_ivlantag, .tx_ctxt_desc_get_ivlantag =
[PATCH V2 RE-SEND 4/7] net: sxgbe: add Checksum offload support for Samsung sxgbe
From: Vipul Pandya vipul.pan...@samsung.com This patch adds TX and RX checksum offload support. Signed-off-by: Vipul Pandya vipul.pan...@samsung.com Neatening-by: Joe Perches j...@perches.com Signed-off-by: Byungho An bh74...@samsung.com --- drivers/net/ethernet/samsung/sxgbe_common.h |6 +++- drivers/net/ethernet/samsung/sxgbe_core.c | 20 drivers/net/ethernet/samsung/sxgbe_desc.c | 27 drivers/net/ethernet/samsung/sxgbe_desc.h |6 ++-- drivers/net/ethernet/samsung/sxgbe_main.c | 46 --- 5 files changed, 84 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/samsung/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe_common.h index 21d8ee6..68e8ad4 100644 --- a/drivers/net/ethernet/samsung/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe_common.h @@ -347,6 +347,10 @@ struct sxgbe_core_ops { void (*set_eee_timer)(void __iomem *ioaddr, const int ls, const int tw); void (*set_eee_pls)(void __iomem *ioaddr, const int link); + + /* Enable disable checksum offload operations */ + void (*enable_rx_csum)(void __iomem *ioaddr); + void (*disable_rx_csum)(void __iomem *ioaddr); }; const struct sxgbe_core_ops *sxgbe_get_core_ops(void); @@ -462,7 +466,7 @@ struct sxgbe_priv_data { struct net_device *dev; struct device *device; struct sxgbe_ops *hw;/* sxgbe specific ops */ - int no_csum_insertion; + int rxcsum_insertion; spinlock_t lock; spinlock_t stats_lock; diff --git a/drivers/net/ethernet/samsung/sxgbe_core.c b/drivers/net/ethernet/samsung/sxgbe_core.c index bf93b16..5885fd6 100644 --- a/drivers/net/ethernet/samsung/sxgbe_core.c +++ b/drivers/net/ethernet/samsung/sxgbe_core.c @@ -217,6 +217,24 @@ static void sxgbe_set_eee_timer(void __iomem *ioaddr, writel(value, ioaddr + SXGBE_CORE_LPI_TIMER_CTRL); } +static void sxgbe_enable_rx_csum(void __iomem *ioaddr) +{ + u32 ctrl; + + ctrl = readl(ioaddr + SXGBE_CORE_RX_CONFIG_REG); + ctrl |= SXGBE_RX_CSUMOFFLOAD_ENABLE; + writel(ctrl, ioaddr + SXGBE_CORE_RX_CONFIG_REG); +} + +static void sxgbe_disable_rx_csum(void __iomem *ioaddr) +{ + u32 ctrl; + + ctrl = readl(ioaddr + SXGBE_CORE_RX_CONFIG_REG); + ctrl = ~SXGBE_RX_CSUMOFFLOAD_ENABLE; + writel(ctrl, ioaddr + SXGBE_CORE_RX_CONFIG_REG); +} + const struct sxgbe_core_ops core_ops = { .core_init = sxgbe_core_init, .dump_regs = sxgbe_core_dump_regs, @@ -233,6 +251,8 @@ const struct sxgbe_core_ops core_ops = { .reset_eee_mode = sxgbe_reset_eee_mode, .set_eee_timer = sxgbe_set_eee_timer, .set_eee_pls = sxgbe_set_eee_pls, + .enable_rx_csum = sxgbe_enable_rx_csum, + .disable_rx_csum = sxgbe_disable_rx_csum, }; const struct sxgbe_core_ops *sxgbe_get_core_ops(void) diff --git a/drivers/net/ethernet/samsung/sxgbe_desc.c b/drivers/net/ethernet/samsung/sxgbe_desc.c index fa21236..8d9ee61 100644 --- a/drivers/net/ethernet/samsung/sxgbe_desc.c +++ b/drivers/net/ethernet/samsung/sxgbe_desc.c @@ -47,6 +47,9 @@ static void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd, p-tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.total_pkt_len = pkt_len; + if (cksum) + p-tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.cksum_ctl = + cic_full; } /* Set VLAN control information */ @@ -250,31 +253,40 @@ static int sxgbe_get_rx_ld_status(struct sxgbe_rx_norm_desc *p) /* Return the RX status looking at the WB fields */ -static void sxgbe_rx_wbstatus(struct sxgbe_rx_norm_desc *p, - struct sxgbe_extra_stats *x) +static int sxgbe_rx_wbstatus(struct sxgbe_rx_norm_desc *p, +struct sxgbe_extra_stats *x, int *checksum) { + int status = 0; + *checksum = CHECKSUM_UNNECESSARY; if (p-rdes23.rx_wb_des23.err_summary) { switch (p-rdes23.rx_wb_des23.err_l2_type) { case RX_GMII_ERR: + status = -EINVAL; x-rx_code_gmii_err++; break; case RX_WATCHDOG_ERR: + status = -EINVAL; x-rx_watchdog_err++; break; case RX_CRC_ERR: + status = -EINVAL; x-rx_crc_err++; break; case RX_GAINT_ERR: + status = -EINVAL; x-rx_gaint_pkt_err++; break; case RX_IP_HDR_ERR: + *checksum = CHECKSUM_NONE; x-ip_hdr_err++; break; case RX_PAYLOAD_ERR: + *checksum = CHECKSUM_NONE; x-ip_payload_err++; break;
[PATCH V2 RE-SEND 7/7] MAINTAINERS: add maintainer for Samsung sxgbe driver
Signed-off-by: Byungho An bh74...@samsung.com --- MAINTAINERS |9 + 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b2cf5cf..344702c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7497,6 +7497,15 @@ S: Supported L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) F: drivers/clk/samsung/ +SAMSUNG SXGBE DRIVERS +M: Byungho An bh74...@samsung.com +M: Girish K S ks.g...@samsung.com +M: Siva Reddy Kallam siva.kal...@samsung.com +M: Vipul Pandya vipul.pan...@samsung.com +S: Supported +L: net...@vger.kernel.org +F: drivers/net/ethernet/samsung/ + SERIAL DRIVERS M: Greg Kroah-Hartman gre...@linuxfoundation.org L: linux-ser...@vger.kernel.org -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: ref: virt-v7.c switching to non_secure mode
Hi Christoffer / uboot, We are able to figure out the issue. PERIPHBASE returned on ARNDALE board was 0x1050 and adding GIC offset was creating an incorrect address. Setting CONFIG_ARM_GIC_BASE_ADDRESS as 0x1048 in arndale.h solves the issue. The u-boot code needs to be fixed for arndale right ? Please confirm Regards Manish armdev Team @FTM On 13-Mar-2014, at 11:20 am, armdev armdev@gmail.com wrote: Got a mail that Andre is not with linaro, Adding Christoffer Dall On 13-Mar-2014, at 11:17 am, armdev armdev@gmail.com wrote: Hi Andrey , This is wrt your patch set which enabled the switch to non-sec and hip mode in armv7. We have a small piece of code which we run in hypmode using the bootm command on arndale board While this code was trying to access the GICD_ISENABLR0 (0x10481100), read was always returning 0, while as per the reset value it should be 0x. Debugged more in u-boot and added prints. This is the log, our observation is that in _nonsec_init() there is something that is causing the issue. Now It can be an issue or a gap in our understanding. Ideally we should be able to read the GICD_ISENABLR value as 0x. Can you please help us in find out how to read GIC values properly in hyp mode. armv7_switch_nonsec cpsr =61d3 REGS Before write to group regs cpsr =61d3 REGS Before _nonsec_init() cpsr =61d3 REGS After _nonsec_init() cpsr =61d3 REGS 0 HYP mode: successful. armv7_switch_hyp cpsr =61da REGS 0 Here is the diff of our modifications. (just added prints) diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c index 2cd604f..f38f125 100644 --- a/arch/arm/cpu/armv7/virt-v7.c +++ b/arch/arm/cpu/armv7/virt-v7.c @@ -107,6 +107,10 @@ int armv7_switch_hyp(void) printf(HYP mode: switch not successful.\n); return -1; } +printf(HYP mode: successful.\n); +printf(%s \r\n,__FUNCTION__); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); return 0; } @@ -116,6 +120,10 @@ int armv7_switch_nonsec(void) unsigned int reg; unsigned itlinesnr, i; +printf(%s \r\n,__FUNCTION__); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); + /* check whether the CPU supports the security extensions */ reg = read_id_pfr1(); if ((reg 0xF0) == 0) { @@ -140,6 +148,9 @@ int armv7_switch_nonsec(void) /* TYPER[4:0] contains an encoded number of available interrupts */ itlinesnr = readl(gic_dist_addr + GICD_TYPER) 0x1f; +printf(Before write to group regs \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); /* set all bits in the GIC group registers to one to allow access * from non-secure state. The first 32 interrupts are private per * CPU and will be set later when enabling the GIC for each core @@ -147,11 +158,19 @@ int armv7_switch_nonsec(void) for (i = 1; i = itlinesnr; i++) writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); -smp_set_core_boot_addr((unsigned long)_smp_pen, -1); -smp_kick_all_cpus(); +//smp_set_core_boot_addr((unsigned long)_smp_pen, -1); +//smp_kick_all_cpus(); +printf(Before _nonsec_init() \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); /* call the non-sec switching code on this CPU also */ _nonsec_init(); +printf(After _nonsec_init() \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); + + return 0; } diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 515facf..53a1212 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -62,7 +62,6 @@ /* select serial console configuration */ #define CONFIG_BAUDRATE 115200 #define EXYNOS5_DEFAULT_UART_OFFSET 0x01 -#define CONFIG_SILENT_CONSOLE /* Console configuration */ #define CONFIG_CONSOLE_MUX @@ -249,4 +248,7 @@ /* Enable Time Command */ #define CONFIG_CMD_TIME +/* Enable jump to hypervisor */ +#define CONFIG_ARMV7_VIRT +#define CONFIG_SMP_PEN_ADDR 0x0 #endif /* __CONFIG_H */ -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 RE-SEND 6/7] net: sxgbe: add ethtool related functions support Samsung sxgbe
From: Vipul Pandya vipul.pan...@samsung.com This patch adds ethtool related functions. Signed-off-by: Vipul Pandya vipul.pan...@samsung.com Neatening-by: Joe Perches j...@perches.com Signed-off-by: Byungho An bh74...@samsung.com --- drivers/net/ethernet/samsung/sxgbe_common.h | 28 +- drivers/net/ethernet/samsung/sxgbe_ethtool.c | 509 +- drivers/net/ethernet/samsung/sxgbe_main.c| 14 +- drivers/net/ethernet/samsung/sxgbe_reg.h |6 + 4 files changed, 538 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/samsung/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe_common.h index b029181..1f65194 100644 --- a/drivers/net/ethernet/samsung/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe_common.h @@ -42,8 +42,12 @@ struct sxgbe_mtl_ops; #define SXGBE_RX_QUEUES 16 /* Max/Min RI Watchdog Timer count value */ -#define SXGBE_MAX_DMA_RIWT 0xff -#define SXGBE_MIN_DMA_RIWT 0x20 +/* Calculated based how much time does it take to fill 256KB Rx memory + * at 10Gb speed at 156MHz clock rate and considered little less then + * the actual value. + */ +#define SXGBE_MAX_DMA_RIWT 0x70 +#define SXGBE_MIN_DMA_RIWT 0x01 /* Tx coalesce parameters */ #define SXGBE_COAL_TX_TIMER4 @@ -203,6 +207,20 @@ enum dma_irq_status { #define SXGBE_FOR_EACH_QUEUE(max_queues, queue_num)\ for (queue_num = 0; queue_num max_queues; queue_num++) +#define DRV_VERSION 1.0.0 + +#define SXGBE_MAX_RX_CHANNELS 16 +#define SXGBE_MAX_TX_CHANNELS 16 + +#define START_MAC_REG_OFFSET 0x +#define MAX_MAC_REG_OFFSET 0x0DFC +#define START_MTL_REG_OFFSET 0x1000 +#define MAX_MTL_REG_OFFSET 0x18FC +#define START_DMA_REG_OFFSET 0x3000 +#define MAX_DMA_REG_OFFSET 0x38FC + +#define REG_SPACE_SIZE 0x2000 + /* sxgbe statistics counters */ struct sxgbe_extra_stats { /* TX/RX IRQ events */ @@ -484,7 +502,8 @@ struct sxgbe_priv_data { int oldlink; int speed; int oldduplex; - unsigned int flow_ctrl; + u8 rx_pause; + u8 tx_pause; unsigned int pause; struct mii_bus *mii; int mii_irq[PHY_MAX_ADDR]; @@ -504,6 +523,7 @@ struct sxgbe_priv_data { u32 adv_ts; int use_riwt; spinlock_t ptp_lock; + struct ptp_clock *ptp_clock; /* EEE-LPI specific members */ struct timer_list eee_ctrl_timer; @@ -542,4 +562,6 @@ const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void); void sxgbe_disable_eee_mode(struct sxgbe_priv_data * const priv); bool sxgbe_eee_init(struct sxgbe_priv_data * const priv); +int sxgbe_set_flow_ctrl(struct sxgbe_priv_data *priv, int rx, int tx); + #endif /* __SXGBE_COMMON_H__ */ diff --git a/drivers/net/ethernet/samsung/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe_ethtool.c index 89b1450..6a16f05 100644 --- a/drivers/net/ethernet/samsung/sxgbe_ethtool.c +++ b/drivers/net/ethernet/samsung/sxgbe_ethtool.c @@ -12,12 +12,17 @@ #define pr_fmt(fmt) KBUILD_MODNAME : fmt +#include linux/clk.h #include linux/interrupt.h #include linux/kernel.h #include linux/netdevice.h +#include linux/net_tstamp.h #include linux/phy.h +#include linux/ptp_clock_kernel.h #include sxgbe_common.h +#include sxgbe_reg.h +#include sxgbe_dma.h struct sxgbe_stats { char stat_string[ETH_GSTRING_LEN]; @@ -33,17 +38,106 @@ struct sxgbe_stats { } static const struct sxgbe_stats sxgbe_gstrings_stats[] = { + /* TX/RX IRQ events */ + SXGBE_STAT(tx_process_stopped_irq), + SXGBE_STAT(tx_ctxt_desc_err), + SXGBE_STAT(tx_threshold), + SXGBE_STAT(rx_threshold), + SXGBE_STAT(tx_pkt_n), + SXGBE_STAT(rx_pkt_n), + SXGBE_STAT(normal_irq_n), + SXGBE_STAT(tx_normal_irq_n), + SXGBE_STAT(rx_normal_irq_n), + SXGBE_STAT(napi_poll), + SXGBE_STAT(tx_clean), + SXGBE_STAT(tx_reset_ic_bit), + SXGBE_STAT(rx_process_stopped_irq), + SXGBE_STAT(rx_underflow_irq), + + /* Bus access errors */ + SXGBE_STAT(fatal_bus_error_irq), + SXGBE_STAT(tx_read_transfer_err), + SXGBE_STAT(tx_write_transfer_err), + SXGBE_STAT(tx_desc_access_err), + SXGBE_STAT(tx_buffer_access_err), + SXGBE_STAT(tx_data_transfer_err), + SXGBE_STAT(rx_read_transfer_err), + SXGBE_STAT(rx_write_transfer_err), + SXGBE_STAT(rx_desc_access_err), + SXGBE_STAT(rx_buffer_access_err), + SXGBE_STAT(rx_data_transfer_err), + SXGBE_STAT(pmt_irq_event_n), + + /* EEE-LPI stats */ SXGBE_STAT(tx_lpi_entry_n), SXGBE_STAT(tx_lpi_exit_n), SXGBE_STAT(rx_lpi_entry_n), SXGBE_STAT(rx_lpi_exit_n), SXGBE_STAT(eee_wakeup_error_n), - SXGBE_STAT(pmt_irq_event_n), + + /* RX specific */ + /* L2 error */ + SXGBE_STAT(rx_code_gmii_err), + SXGBE_STAT(rx_watchdog_err), + SXGBE_STAT(rx_crc_err), + SXGBE_STAT(rx_gaint_pkt_err), +
Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
2014-03-12 20:16 GMT+09:00 Tomasz Figa t.f...@samsung.com: On 12.03.2014 11:08, Inki Dae wrote: 2014-03-07 19:00 GMT+09:00 Andrzej Hajda a.ha...@samsung.com: On 03/05/2014 03:56 AM, Inki Dae wrote: Hi Andrzej, Thanks for your contributions. 2014-02-12 20:31 GMT+09:00 Andrzej Hajda a.ha...@samsung.com: Hi, This patchset adds drivers and bindings to the following devices: - Exynos DSI master, - S6E8AA0 DSI panel, - TC358764 DSI/LVDS bridge, - HV070WSA-100 LVDS panel. It adds also display support in DTS files for the following boards: - Exynos4210/Trats, - Exynos4412/Trats2, - Exynos5250/Arndale. Things worth mentioning: 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie. the driver exposes drm_panel interface on DSI side, and interact with panels on LVDS side using drm_panel framework. This approach seems to me simpler and more natural than using drm_bridge. Can you give me more details about why you think better to use panel framework than using drm_bridge? Simpler and more natural are ambiguous to me. In this particular case DSI master expects on the other end any device having DSI slave interface, it could be panel or bridge. So it seems natural that both types of slave devices should expose the same interface also on programming level. Another problem with drm_bridge is that it is not scalable - if some manufacturer will decide to add another block between the bridge and the panel there is no drm component which can be used for it. Using drm_panel the way I have used in toshiba bridge makes scalability possible, it will be only a matter of adding a driver for new block and making proper links in device tree, I see no easy way of doing it with drm_bridge approach. Now drm_bridge may not cover all hardware. However drm_bridge has already been merged to mainline so I think we need to use drm_bridge somehow instead of using other one, and also we could extend drm_bridge if needed. It would be definitely impossible for a new framework to cover all hardware because there may be other hardware not appeared yet. That is what we are doing for mainline until now. Well, maybe drm_bridge has been merged, but so has been drm_panel. Moreover, merged code is not carved in stone, if there is a better option that could replace it, users of it can be converted to the new approach and the old one can be removed. As I believe Andrzej has demonstrated, drm_panel framework is clearly superior over drm_bridge and I can't think of any good reason why it couldn't become more generic and replace drm_bridge. Of course it can be renamed then to something more generic appropriately. Using same drm_panel framework for LDVS bridge and real panel drivers isn't reasonable to me as now because drm_panel framework would be for real panel device even if the use of drm_panel framework looks like suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver using drm_bride stuff, is good enough, and that would be why drm_bridge exists and why drm_encoder has drm_bridge. And I'm finding more generic way, how to handle LVDS bridge using super node so that LVDS bridge driver isn't embedded to connector drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be done at top level of Exynos drm. Once the binding is done, encoder of display bus driver will have drm_bridge object of LVDS bridge driver so that display bus driver can handle LVDS bridge driver. Could you explain what you mean by dt binding of LVDS bridge can be done at top level of Exynos drm ? How it will look like if there will be more bridges, one for DSI, one for HDMI, etc... What if there will be two bridges in one chain. How it will cope with video pipeline bindings? it was just my idea so I have no implementation about it yet. My idea is that crtc and encoder are binded at top level of Exynos drm as is. And for bridge support, the only difference is, in case that encoder driver has bridge, the dt binding of the encoder driver is done once last one between encoder and bridge driver is binded. It would mean that bridge driver can use driver model and it doesn't need to concern about probe order issue. For this, encoder driver with bridge, MIPI-DSI or eDP, would need to use component interfaces specific to Exynos drm. As a result, once the dt bindings of crtc and encoder are completed at top level, encoder driver has its own drm_bridge for bridge, and dt binding you proposed could be used without any change, and drm_panel could also be used only for real lcd panel driver. And below is a block diagram I think, DRM KMS / | \ / | \ crtc encoder connector | / \ |
[PATCHv2 4/8] devfreq: exynos4: Fix bug of resource leak and code clean on probe()
This patch fix bug about resource leak when happening probe fail and code clean to add debug message. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- drivers/devfreq/exynos/exynos4_bus.c | 32 ++-- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index a2a3a47..152a3e9 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -1152,8 +1152,11 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) dev_err(dev, Cannot determine the device id %d\n, data-type); err = -EINVAL; } - if (err) + if (err) { + dev_err(dev, Cannot initialize busfreq table %d\n, +data-type); return err; + } rcu_read_lock(); opp = dev_pm_opp_find_freq_floor(dev, @@ -1176,7 +1179,7 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) if (IS_ERR(data-devfreq)) { dev_err(dev, Failed to add devfreq device\n); err = PTR_ERR(data-devfreq); - goto err_opp; + goto err_devfreq; } /* @@ -1185,18 +1188,35 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) */ busfreq_mon_reset(data); - devfreq_register_opp_notifier(dev, data-devfreq); + /* Register opp_notifier for Exynos4 busfreq */ + err = devfreq_register_opp_notifier(dev, data-devfreq); + if (err 0) { + dev_err(dev, Failed to register opp notifier\n); + goto err_notifier_opp; + } + /* Register pm_notifier for Exynos4 busfreq */ err = register_pm_notifier(data-pm_notifier); if (err) { dev_err(dev, Failed to setup pm notifier\n); - devfreq_remove_device(data-devfreq); - return err; + goto err_notifier_pm; } return 0; -err_opp: +err_notifier_pm: + devfreq_unregister_opp_notifier(dev, data-devfreq); +err_notifier_opp: + /* +* The devfreq_remove_device() would execute finally devfreq-profile +* -exit(). To avoid duplicate resource free operation, return directly +* before executing resource free below 'err_devfreq' goto statement. +*/ + devfreq_remove_device(data-devfreq); + + return err; + +err_devfreq: regulator_disable(data-vdd_int); if (data-type == TYPE_BUSF_EXYNOS4x12) regulator_disable(data-vdd_mif); -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 0/8] devfreq: exynos4: Support dt and use common ppmu driver
This patchset support devicetree and use common ppmu driver instead of individual code of exynos4_bus.c to remove duplicate code. Also this patchset get the resources for busfreq from dt data by using DT helper function. - PPMU register address - PPMU clock - Regulator for INT/MIF block This patchset use SET_SYSTEM_SLEEP_PM_OPS macro intead of legacy method. To remove power-leakage in suspend state, before entering suspend state, disable ppmu clocks. Changes from v1: - Add exynos4_bus.txt documentation for devicetree guide - Fix probe failure if CONFIG_PM_OPP is disabled - Fix typo and resource leak(regulator/clock/memory) when happening probe failure - Add additionally comment for PPMU usage instead of previous PPC - Split separate patch to remove ambiguous of patch Chanwoo Choi (8): devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data devfreq: exynos4: Add ppmu's clock control and code clean about regulator control devfreq: exynos4: Fix bug of resource leak and code clean on probe() devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro devfreq: exynos4: Fix power-leakage of clock on suspend state devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail devfreq: exynos4: Add busfreq driver for exynos4210/exynos4x12 .../devicetree/bindings/devfreq/exynos4_bus.txt| 49 +++ drivers/devfreq/Kconfig| 1 + drivers/devfreq/exynos/Makefile| 2 +- drivers/devfreq/exynos/exynos4_bus.c | 415 ++--- 4 files changed, 341 insertions(+), 126 deletions(-) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 1/8] devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC
This patch support DT(DeviceTree) method to probe exynos4_bus and get device id of each Exynos4 SoC by using dt helper function. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- drivers/devfreq/exynos/exynos4_bus.c | 26 +- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index e07b0c6..168a7c6 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -23,6 +23,7 @@ #include linux/devfreq.h #include linux/platform_device.h #include linux/regulator/consumer.h +#include linux/of.h #include linux/module.h /* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */ @@ -1017,6 +1018,28 @@ unlock: return NOTIFY_DONE; } +static struct of_device_id exynos4_busfreq_id_match[] = { + { + .compatible = samsung,exynos4210-busfreq, + .data = (void *)TYPE_BUSF_EXYNOS4210, + }, { + .compatible = samsung,exynos4x12-busfreq, + .data = (void *)TYPE_BUSF_EXYNOS4x12, + }, +}; + +static int exynos4_busfreq_get_driver_data(struct platform_device *pdev) +{ + struct device *dev = pdev-dev; + const struct of_device_id *match; + + match = of_match_node(exynos4_busfreq_id_match, dev-of_node); + if (!match) + return -ENODEV; + + return (int) match-data; +} + static int exynos4_busfreq_probe(struct platform_device *pdev) { struct busfreq_data *data; @@ -1030,7 +1053,7 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) return -ENOMEM; } - data-type = pdev-id_entry-driver_data; + data-type = exynos4_busfreq_get_driver_data(pdev); data-dmc[0].hw_base = S5P_VA_DMC0; data-dmc[1].hw_base = S5P_VA_DMC1; data-pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event; @@ -1135,6 +1158,7 @@ static struct platform_driver exynos4_busfreq_driver = { .name = exynos4-busfreq, .owner = THIS_MODULE, .pm = exynos4_busfreq_pm, + .of_match_table = exynos4_busfreq_id_match, }, }; -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 6/8] devfreq: exynos4: Fix power-leakage of clock on suspend state
This patch disable ppmu clocks before entering suspend state to remove power-leakage and enable ppmu clocks on resume function. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- drivers/devfreq/exynos/exynos4_bus.c | 25 - 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index 9576ee2..3d35063 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -1251,14 +1251,37 @@ static int exynos4_busfreq_remove(struct platform_device *pdev) static int exynos4_busfreq_resume(struct device *dev) { struct busfreq_data *data = dev_get_drvdata(dev); + int i; + + /* Enable clock after wake-up from suspend state */ + for (i = 0; i PPMU_END; i++) + clk_prepare_enable(data-clk_ppmu[i]); + + /* Reset PPMU to check utilization again */ busfreq_mon_reset(data); + return 0; } + +static int exynos4_busfreq_suspend(struct device *dev) +{ + struct busfreq_data *data = dev_get_drvdata(dev); + int i; + + /* +* Disable clock before entering suspend state +* to reduce leakage power on suspend state. +*/ + for (i = 0; i PPMU_END; i++) + clk_disable_unprepare(data-clk_ppmu[i]); + + return 0; +}; #endif static const struct dev_pm_ops exynos4_busfreq_pm = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, exynos4_busfreq_resume) + SET_SYSTEM_SLEEP_PM_OPS(exynos4_busfreq_suspend, exynos4_busfreq_resume) }; static const struct platform_device_id exynos4_busfreq_id[] = { -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 7/8] devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail
This patch add CONFIG_PM_OPP dependecy to exynos4_bus driver to fix probe fail as following log: [3.721389] exynos4-busfreq busfreq.3: Fail to add opp entries. [3.721697] exynos4-busfreq: probe of busfreq.3 failed with error -22 If CONFIG_PM_OPP is disabled, dev_pm_opp_find_freq_floor() in xxx_probe() will always return -EINVAL error. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- drivers/devfreq/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 7d2f435..b2de2a1 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -70,6 +70,7 @@ config ARM_EXYNOS4_BUS_DEVFREQ depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) !ARCH_MULTIPLATFORM select ARCH_HAS_OPP select DEVFREQ_GOV_SIMPLE_ONDEMAND + select PM_OPP help This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int) and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int). -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro
This patch use SET_SYSTEM_SLEEP_PM_OPS macro instead of legacy method. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- drivers/devfreq/exynos/exynos4_bus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index 152a3e9..9576ee2 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -1247,6 +1247,7 @@ static int exynos4_busfreq_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP static int exynos4_busfreq_resume(struct device *dev) { struct busfreq_data *data = dev_get_drvdata(dev); @@ -1254,9 +1255,10 @@ static int exynos4_busfreq_resume(struct device *dev) busfreq_mon_reset(data); return 0; } +#endif static const struct dev_pm_ops exynos4_busfreq_pm = { - .resume = exynos4_busfreq_resume, + SET_SYSTEM_SLEEP_PM_OPS(NULL, exynos4_busfreq_resume) }; static const struct platform_device_id exynos4_busfreq_id[] = { -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 3/8] devfreq: exynos4: Add ppmu's clock control and code clean about regulator control
There are not the clock controller of ppmudmc0/1. This patch control the clock of ppmudmc0/1 which is used for monitoring memory bus utilization. Also, this patch code clean about regulator control and free resource when calling exit/remove function. For example, busfreq@106A { compatible = samsung,exynos4x12-busfreq; /* Clock for PPMUDMC0/1 */ clocks = clock CLK_PPMUDMC0, clock CLK_PPMUDMC1; clock-names = ppmudmc0, ppmudmc1; /* Regulator for MIF/INT block */ vdd_mif-supply = buck1_reg; vdd_int-supply = buck3_reg; }; Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- drivers/devfreq/exynos/exynos4_bus.c | 114 ++- 1 file changed, 100 insertions(+), 14 deletions(-) diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index 1a0effa..a2a3a47 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -62,6 +62,11 @@ enum exynos_ppmu_idx { PPMU_END, }; +static const char *exynos_ppmu_clk_name[] = { + [PPMU_DMC0] = ppmudmc0, + [PPMU_DMC1] = ppmudmc1, +}; + #define EX4210_LV_MAX LV_2 #define EX4x12_LV_MAX LV_4 #define EX4210_LV_NUM (LV_2 + 1) @@ -86,6 +91,7 @@ struct busfreq_data { struct regulator *vdd_mif; /* Exynos4412/4212 only */ struct busfreq_opp_info curr_oppinfo; struct exynos_ppmu ppmu[PPMU_END]; + struct clk *clk_ppmu[PPMU_END]; struct notifier_block pm_notifier; struct mutex lock; @@ -722,8 +728,26 @@ static int exynos4_bus_get_dev_status(struct device *dev, static void exynos4_bus_exit(struct device *dev) { struct busfreq_data *data = dev_get_drvdata(dev); + int i; + + /* +* Un-map memory map and disable regulator/clocks +* to prevent power leakage. +*/ + regulator_disable(data-vdd_int); + if (data-type == TYPE_BUSF_EXYNOS4x12) + regulator_disable(data-vdd_mif); + + for (i = 0; i PPMU_END; i++) { + if (data-clk_ppmu[i]) + clk_disable_unprepare(data-clk_ppmu[i]); + } - devfreq_unregister_opp_notifier(dev, data-devfreq); + for (i = 0; i PPMU_END; i++) { + if (data-ppmu[i].hw_base) + iounmap(data-ppmu[i].hw_base); + + } } static struct devfreq_dev_profile exynos4_devfreq_profile = { @@ -987,6 +1011,7 @@ static int exynos4_busfreq_parse_dt(struct busfreq_data *data) { struct device *dev = data-dev; struct device_node *np = dev-of_node; + const char **clk_name = exynos_ppmu_clk_name; int i, ret; if (!np) { @@ -1005,8 +1030,70 @@ static int exynos4_busfreq_parse_dt(struct busfreq_data *data) } } + /* +* Get PPMU's clocks to control them. But, if PPMU's clocks +* is default 'pass' state, this driver don't need control +* PPMU's clock. +*/ + for (i = 0; i PPMU_END; i++) { + data-clk_ppmu[i] = devm_clk_get(dev, clk_name[i]); + if (IS_ERR_OR_NULL(data-clk_ppmu[i])) { + dev_warn(dev, Cannot get %s clock\n, clk_name[i]); + data-clk_ppmu[i] = NULL; + } + + ret = clk_prepare_enable(data-clk_ppmu[i]); + if (ret 0) { + dev_warn(dev, Cannot enable %s clock\n, clk_name[i]); + data-clk_ppmu[i] = NULL; + goto err_clocks; + } + } + + /* Get regulator to control voltage of int block */ + data-vdd_int = devm_regulator_get(dev, vdd_int); + if (IS_ERR(data-vdd_int)) { + dev_err(dev, Failed to get the regulator of vdd_int\n); + ret = PTR_ERR(data-vdd_int); + goto err_clocks; + } + ret = regulator_enable(data-vdd_int); + if (ret 0) { + dev_err(dev, Failed to enable regulator of vdd_int\n); + goto err_clocks; + } + + switch (data-type) { + case TYPE_BUSF_EXYNOS4210: + break; + case TYPE_BUSF_EXYNOS4x12: + /* Get regulator to control voltage of mif blk if Exynos4x12 */ + data-vdd_mif = devm_regulator_get(dev, vdd_mif); + if (IS_ERR(data-vdd_mif)) { + dev_err(dev, Failed to get the regulator vdd_mif\n); + ret = PTR_ERR(data-vdd_mif); + goto err_regulator; + } + ret = regulator_enable(data-vdd_mif); + if (ret 0) { + dev_err(dev, Failed to enable regulator of vdd_mif\n); + goto err_regulator; + } + break; + default: + dev_err(dev, Unknown device type : %d\n, data-type); + return -EINVAL; +
[PATCHv2 2/8] devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data
This patch use common ppmu driver of exynos_ppmu.c driver instead of individual function related to PPC because PPMU is integrated module with both PPC and Bus event generator. When using PPMU to get bus performance read/write event, exynos4_bus.c don't need to consider memory type. And get ppmu address from dt data by using dt helper function (of_iomap). And then this patch delete duplicate defined structure/enum. For example, busfreq@106A { compatible = samsung,exynos4x12-busfreq; reg = 0x106A 0x2000, 0x106B 0x2000; regs-name = PPMU_DMC0, PPMU_DMC1; }; Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- drivers/devfreq/exynos/Makefile | 2 +- drivers/devfreq/exynos/exynos4_bus.c | 222 ++- 2 files changed, 117 insertions(+), 107 deletions(-) diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile index bfaaf5b..49bc917 100644 --- a/drivers/devfreq/exynos/Makefile +++ b/drivers/devfreq/exynos/Makefile @@ -1,3 +1,3 @@ # Exynos DEVFREQ Drivers -obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos4_bus.o +obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos_ppmu.o exynos4_bus.o obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos_ppmu.o exynos5_bus.o diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index 168a7c6..1a0effa 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -24,17 +24,19 @@ #include linux/platform_device.h #include linux/regulator/consumer.h #include linux/of.h +#include linux/of_address.h #include linux/module.h +#include mach/map.h + +#include exynos_ppmu.h +#include exynos4_bus.h + /* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */ #ifdef CONFIG_EXYNOS_ASV extern unsigned int exynos_result_of_asv; #endif -#include mach/map.h - -#include exynos4_bus.h - #define MAX_SAFEVOLT 120 /* 1.2V */ enum exynos4_busf_type { @@ -45,22 +47,6 @@ enum exynos4_busf_type { /* Assume that the bus is saturated if the utilization is 40% */ #define BUS_SATURATION_RATIO 40 -enum ppmu_counter { - PPMU_PMNCNT0 = 0, - PPMU_PMCCNT1, - PPMU_PMNCNT2, - PPMU_PMNCNT3, - PPMU_PMNCNT_MAX, -}; -struct exynos4_ppmu { - void __iomem *hw_base; - unsigned int ccnt; - unsigned int event; - unsigned int count[PPMU_PMNCNT_MAX]; - bool ccnt_overflow; - bool count_overflow[PPMU_PMNCNT_MAX]; -}; - enum busclk_level_idx { LV_0 = 0, LV_1, @@ -69,6 +55,13 @@ enum busclk_level_idx { LV_4, _LV_END }; + +enum exynos_ppmu_idx { + PPMU_DMC0, + PPMU_DMC1, + PPMU_END, +}; + #define EX4210_LV_MAX LV_2 #define EX4x12_LV_MAX LV_4 #define EX4210_LV_NUM (LV_2 + 1) @@ -92,7 +85,7 @@ struct busfreq_data { struct regulator *vdd_int; struct regulator *vdd_mif; /* Exynos4412/4212 only */ struct busfreq_opp_info curr_oppinfo; - struct exynos4_ppmu dmc[2]; + struct exynos_ppmu ppmu[PPMU_END]; struct notifier_block pm_notifier; struct mutex lock; @@ -102,12 +95,6 @@ struct busfreq_data { unsigned int top_divtable[_LV_END]; }; -struct bus_opp_table { - unsigned int idx; - unsigned long clk; - unsigned long volt; -}; - /* 4210 controls clock of mif and voltage of int */ static struct bus_opp_table exynos4210_busclk_table[] = { {LV_0, 40, 115}, @@ -525,27 +512,22 @@ static int exynos4x12_set_busclk(struct busfreq_data *data, return 0; } - static void busfreq_mon_reset(struct busfreq_data *data) { unsigned int i; - for (i = 0; i 2; i++) { - void __iomem *ppmu_base = data-dmc[i].hw_base; + for (i = 0; i PPMU_END; i++) { + void __iomem *ppmu_base = data-ppmu[i].hw_base; - /* Reset PPMU */ - __raw_writel(0x800f, ppmu_base + 0xf010); - __raw_writel(0x800f, ppmu_base + 0xf050); - __raw_writel(0x6, ppmu_base + 0xf000); - __raw_writel(0x0, ppmu_base + 0xf100); + /* Reset the performance and cycle counters */ + exynos_ppmu_reset(ppmu_base); - /* Set PPMU Event */ - data-dmc[i].event = 0x6; - __raw_writel(((data-dmc[i].event 12) | 0x1), -ppmu_base + 0xfc); + /* Setup count registers to monitor read/write transactions */ + data-ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT; + exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3, + data-ppmu[i].event[PPMU_PMNCNT3]); - /* Start PPMU */ - __raw_writel(0x1, ppmu_base + 0xf000); + exynos_ppmu_start(ppmu_base); } } @@ -553,23 +535,20 @@ static void exynos4_read_ppmu(struct busfreq_data *data) { int i,
[PATCHv2 8/8] devfreq: exynos4: Add busfreq driver for exynos4210/exynos4x12
This patch add busfreq driver for Exynos4210/Exynos4x12 memory interface and bus to support DVFS(Dynamic Voltage Frequency Scaling) according to PPMU counters. PPMU (Performance Profiling Monitorings Units) of Exynos4 SoC provides PPMU counters for DMC(Dynamic Memory Controller) to check memory bus utilization and then busfreq driver adjusts dynamically the operating frequency/voltage by using DEVFREQ Subsystem. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- .../devicetree/bindings/devfreq/exynos4_bus.txt| 49 ++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt diff --git a/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt new file mode 100644 index 000..2a83fcc --- /dev/null +++ b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt @@ -0,0 +1,49 @@ + +Exynos4210/4x12 busfreq driver +- + +Exynos4210/4x12 Soc busfreq driver with devfreq for Memory bus frequency/voltage +scaling according to PPMU counters of memory controllers + +Required properties: +- compatible : should contain Exynos4 SoC type as follwoing: + - samsung,exynos4x12-busfreq for Exynos4x12 + - samsung,exynos4210-busfreq for Exynos4210 +- reg : offset and length of the ppmudmc0/1 + - PPMU (Performance Profiling Monitoring Units) + : It is to profile performance event of DMC(Dynamic Memory + Controller) So, exynos4_bus.c can check memory bus utilization + by using PPMU of Exynos4 SoC. +- clocks : clock number of ppmudmc0/1 +- clock-names : clock name of ppmudmc0/1 +- vdd_int-supply: regulator for interface block of Exynos4 + +Optional properties: +- vdd_mif-supply: regulator for DMC block of Exynos4x12 if Exynos4x12 Soc +- regs-name: register name of ppmudmc0/1 + +All the required listed above must be defined under code busfreq with devfreq + +Exmaple: +For Exynos4210 busfreq, + busfreq@106A { + compatible = samsung,exynos4210-busfreq; + reg = 0x106A 0x2000, 0x106B 0x2000; + regs-name = PPMU_DMC0, PPMU_DMC1; + clocks = clock CLK_PPMUDMC0, clock CLK_PPMUDMC1; + clock-names = ppmudmc0, ppmudmc1; + + vdd_int-supply = buck3_reg; + }; + +For Exynos4x12 busfreq, + busfreq@106A { + compatible = samsung,exynos4x12-busfreq; + reg = 0x106A 0x2000, 0x106B 0x2000; + regs-name = PPMU_DMC0, PPMU_DMC1; + clocks = clock CLK_PPMUDMC0, clock CLK_PPMUDMC1; + clock-names = ppmudmc0, ppmudmc1; + + vdd_mif-suppy = buck1_reg; + vdd_int-supply = buck3_reg; + }; -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [U-Boot] ref: virt-v7.c switching to non_secure mode
Hi, We are able to figure out the issue. PERIPHBASE returned on ARNDALE board was 0x1050 and adding GIC offset was creating an incorrect address. please see: https://github.com/apritzel/u-boot-hypmode/commit/5d9c4209907c6d67dadd033887a30c2f10efeb4c Setting CONFIG_ARM_GIC_BASE_ADDRESS as 0x1048 in arndale.h solves the issue. Yes, I spotted that before and deliberately introduced that variable for the Exynos SoCs. The u-boot code needs to be fixed for arndale right ? Please confirm I could get the Arndale to boot with this above patch. But only after a warm reboot: 1) boot the board up, load the kernel and launch it: Linux will reboot very early (before any useful output via earlyprintk) 2) (back in u-boot:) load the kernel again and launch it: works I got both cores in HYP mode and KVM initialized fine. I lost access to my board, so if you could debug this I would be grateful. Thanks, Andre. Regards Manish armdev Team @FTM On 13-Mar-2014, at 11:20 am, armdev armdev@gmail.com wrote: Got a mail that Andre is not with linaro, Adding Christoffer Dall On 13-Mar-2014, at 11:17 am, armdev armdev@gmail.com wrote: Hi Andrey , This is wrt your patch set which enabled the switch to non-sec and hip mode in armv7. We have a small piece of code which we run in hypmode using the bootm command on arndale board While this code was trying to access the GICD_ISENABLR0 (0x10481100), read was always returning 0, while as per the reset value it should be 0x. Debugged more in u-boot and added prints. This is the log, our observation is that in _nonsec_init() there is something that is causing the issue. Now It can be an issue or a gap in our understanding. Ideally we should be able to read the GICD_ISENABLR value as 0x. Can you please help us in find out how to read GIC values properly in hyp mode. armv7_switch_nonsec cpsr =61d3 REGS Before write to group regs cpsr =61d3 REGS Before _nonsec_init() cpsr =61d3 REGS After _nonsec_init() cpsr =61d3 REGS 0 HYP mode: successful. armv7_switch_hyp cpsr =61da REGS 0 Here is the diff of our modifications. (just added prints) diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c index 2cd604f..f38f125 100644 --- a/arch/arm/cpu/armv7/virt-v7.c +++ b/arch/arm/cpu/armv7/virt-v7.c @@ -107,6 +107,10 @@ int armv7_switch_hyp(void) printf(HYP mode: switch not successful.\n); return -1; } + printf(HYP mode: successful.\n); + printf(%s \r\n,__FUNCTION__); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); return 0; } @@ -116,6 +120,10 @@ int armv7_switch_nonsec(void) unsigned int reg; unsigned itlinesnr, i; + printf(%s \r\n,__FUNCTION__); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); + /* check whether the CPU supports the security extensions */ reg = read_id_pfr1(); if ((reg 0xF0) == 0) { @@ -140,6 +148,9 @@ int armv7_switch_nonsec(void) /* TYPER[4:0] contains an encoded number of available interrupts */ itlinesnr = readl(gic_dist_addr + GICD_TYPER) 0x1f; + printf(Before write to group regs \r\n); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); /* set all bits in the GIC group registers to one to allow access * from non-secure state. The first 32 interrupts are private per * CPU and will be set later when enabling the GIC for each core @@ -147,11 +158,19 @@ int armv7_switch_nonsec(void) for (i = 1; i = itlinesnr; i++) writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); - smp_set_core_boot_addr((unsigned long)_smp_pen, -1); - smp_kick_all_cpus(); + //smp_set_core_boot_addr((unsigned long)_smp_pen, -1); + //smp_kick_all_cpus(); + printf(Before _nonsec_init() \r\n); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); /* call the non-sec switching code on this CPU also */ _nonsec_init(); + printf(After _nonsec_init() \r\n); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); + + return 0; } diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 515facf..53a1212 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -62,7 +62,6 @@ /* select serial console configuration */ #define CONFIG_BAUDRATE 115200 #define EXYNOS5_DEFAULT_UART_OFFSET 0x01 -#define CONFIG_SILENT_CONSOLE /* Console configuration */ #define CONFIG_CONSOLE_MUX @@ -249,4 +248,7 @@ /* Enable Time Command */ #define CONFIG_CMD_TIME +/* Enable jump to hypervisor */ +#define CONFIG_ARMV7_VIRT +#define CONFIG_SMP_PEN_ADDR 0x0 #endif /* __CONFIG_H */ ___ U-Boot mailing list u-b...@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot -- IMPORTANT NOTICE: The contents of this email and any
[PATCH v2 1/3] clk: s2mps11: Add support for S2MPS14 clocks
This patch adds support for S2MPS14 PMIC clocks (BT and AP) to the s2mps11 clock driver. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com Reviewed-by: Yadwinder Singh Brar yadi.b...@samsung.com --- drivers/clk/Kconfig |8 +++--- drivers/clk/clk-s2mps11.c | 61 ++--- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 6f56d3a4f010..8f9ce8ba036d 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -65,12 +65,12 @@ config COMMON_CLK_SI570 clock generators. config COMMON_CLK_S2MPS11 - tristate Clock driver for S2MPS11/S5M8767 MFD + tristate Clock driver for S2MPS1X/S5M8767 MFD depends on MFD_SEC_CORE ---help--- - This driver supports S2MPS11/S5M8767 crystal oscillator clock. These - multi-function devices have 3 fixed-rate oscillators, clocked at - 32KHz each. + This driver supports S2MPS11/S2MPS14/S5M8767 crystal oscillator + clock. These multi-function devices have two (S2MPS14) or three + (S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each. config CLK_TWL6040 tristate External McPDM functional clock from twl6040 diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 508875535e1e..8dafb552274f 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -1,7 +1,7 @@ /* * clk-s2mps11.c - Clock driver for S2MPS11. * - * Copyright (C) 2013 Samsung Electornics + * Copyright (C) 2013,2014 Samsung Electornics * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -13,10 +13,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include linux/module.h @@ -27,6 +23,7 @@ #include linux/clk-provider.h #include linux/platform_device.h #include linux/mfd/samsung/s2mps11.h +#include linux/mfd/samsung/s2mps14.h #include linux/mfd/samsung/s5m8767.h #include linux/mfd/samsung/core.h @@ -125,7 +122,21 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { }, }; -static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev) +static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { + [S2MPS11_CLK_AP] = { + .name = s2mps14_ap, + .ops = s2mps11_clk_ops, + .flags = CLK_IS_ROOT, + }, + [S2MPS11_CLK_BT] = { + .name = s2mps14_bt, + .ops = s2mps11_clk_ops, + .flags = CLK_IS_ROOT, + }, +}; + +static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, + struct clk_init_data *clks_init) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev-dev.parent); struct device_node *clk_np; @@ -145,9 +156,12 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev) if (!clk_table) return ERR_PTR(-ENOMEM); - for (i = 0; i S2MPS11_CLKS_NUM; i++) + for (i = 0; i S2MPS11_CLKS_NUM; i++) { + if (!clks_init[i].name) + continue; /* Skip clocks not present in some devices */ of_property_read_string_index(clk_np, clock-output-names, i, - s2mps11_clks_init[i].name); + clks_init[i].name); + } return clk_np; } @@ -158,6 +172,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev) struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; struct device_node *clk_np = NULL; unsigned int s2mps11_reg; + struct clk_init_data *clks_init; int i, ret = 0; u32 val; @@ -168,25 +183,33 @@ static int s2mps11_clk_probe(struct platform_device *pdev) s2mps11_clk = s2mps11_clks; - clk_np = s2mps11_clk_parse_dt(pdev); - if (IS_ERR(clk_np)) - return PTR_ERR(clk_np); - switch (platform_get_device_id(pdev)-driver_data) { case S2MPS11X: s2mps11_reg = S2MPS11_REG_RTC_CTRL; + clks_init = s2mps11_clks_init; + break; + case S2MPS14X: + s2mps11_reg = S2MPS14_REG_RTCCTRL; + clks_init = s2mps14_clks_init; break; case S5M8767X: s2mps11_reg = S5M8767_REG_CTRL1; + clks_init = s2mps11_clks_init; break; default: dev_err(pdev-dev, Invalid device type\n); return -EINVAL; }; + clk_np = s2mps11_clk_parse_dt(pdev, clks_init);
[PATCH v2 0/3] clk: s2mps11: Add support for S2MPS14 clocks
Hi, This is second version of patchset adding support for the S2MPS14 device to the s2mps11 clock driver. The patchset *depends on*: == 1. Work done by Tushar Behera: [PATCH V2 0/2] Add support for clocks in S5M8767 http://thread.gmane.org/gmane.linux.kernel.samsung-soc/27264 2. Support for S2MPS14 in main sec-core MFD driver (already in linux-next and Lee's tree). Changes since v1: = 1. Patch 1/3: Update driver description in Kconfig. 2. Patch 2/3: Add of_compatible to all MFD cells. 3. Add Yadwinder's Review-by. Best regards, Krzysztof Krzysztof Kozlowski (3): clk: s2mps11: Add support for S2MPS14 clocks mfd: sec-core: Add of_compatible strings for MFD cells Documentation: mfd: s2mps11: Describe S5M8767 and S2MPS14 clocks Documentation/devicetree/bindings/mfd/s2mps11.txt | 24 +--- drivers/clk/Kconfig |8 +-- drivers/clk/clk-s2mps11.c | 61 - drivers/mfd/sec-core.c|8 +++ 4 files changed, 73 insertions(+), 28 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/3] mfd: sec-core: Add of_compatible strings for MFD cells
Add of_compatible strings for MFD cells for regulator, clock and RTC drivers in S5M8767, S2MPS11 and S2MPS14 PMIC-s. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com --- drivers/mfd/sec-core.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index d163c66edebb..c5b9b95b2099 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -55,28 +55,36 @@ static const struct mfd_cell s5m8763_devs[] = { static const struct mfd_cell s5m8767_devs[] = { { .name = s5m8767-pmic, + .of_compatible = samsung,s5m8767-regulators, }, { .name = s5m-rtc, + .of_compatible = samsung,s5m8767-rtc, }, { .name = s5m8767-clk, + .of_compatible = samsung,s5m8767-clk, } }; static const struct mfd_cell s2mps11_devs[] = { { .name = s2mps11-pmic, + .of_compatible = samsung,s2mps11-regulators, }, { .name = s2mps11-clk, + .of_compatible = samsung,s2mps11-clk, } }; static const struct mfd_cell s2mps14_devs[] = { { .name = s2mps14-pmic, + .of_compatible = samsung,s2mps14-regulators, }, { .name = s2mps14-rtc, + .of_compatible = samsung,s2mps14-rtc, }, { .name = s2mps14-clk, + .of_compatible = samsung,s2mps14-clk, } }; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/3] Documentation: mfd: s2mps11: Describe S5M8767 and S2MPS14 clocks
Add bindings documentation for clocks on S5M8767 and S2MPS14 devices. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com Cc: Tomasz Figa t.f...@samsung.com Cc: devicet...@vger.kernel.org Cc: Rob Herring robh...@kernel.org Cc: Pawel Moll pawel.m...@arm.com Cc: Mark Rutland mark.rutl...@arm.com Cc: Ian Campbell ijc+devicet...@hellion.org.uk Cc: Kumar Gala ga...@codeaurora.org --- Documentation/devicetree/bindings/mfd/s2mps11.txt | 24 + 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt index 15ee89c3cc7b..67ea05ca8050 100644 --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt @@ -16,20 +16,25 @@ Optional properties: - interrupts: Interrupt specifiers for interrupt sources. Optional nodes: -- clocks: s2mps11 provides three(AP/CP/BT) buffered 32.768 KHz outputs, so to - register these as clocks with common clock framework instantiate a sub-node - named clocks. It uses the common clock binding documented in : +- clocks: s2mps11 and s5m8767 provide three(AP/CP/BT) buffered 32.768 KHz + outputs, so to register these as clocks with common clock framework + instantiate a sub-node named clocks. It uses the common clock binding + documented in : [Documentation/devicetree/bindings/clock/clock-bindings.txt] + The s2mps14 provides two (AP/BT) buffered 32.768 KHz outputs. - #clock-cells: should be 1. - The following is the list of clocks generated by the controller. Each clock is assigned an identifier and client nodes use this identifier to specify the clock which they consume. -Clock ID --- -32KhzAP0 -32KhzCP1 -32KhzBT2 +Clock ID Devices +-- +32KhzAP0S2MPS11, S2MPS14, S5M8767 +32KhzCP1S2MPS11, S5M8767 +32KhzBT2S2MPS11, S2MPS14, S5M8767 + + - compatible: Should be one of: samsung,s2mps11-clk, samsung,s2mps14-clk, + samsung,s5m8767-clk - regulators: The regulators of s2mps11 that have to be instantiated should be included in a sub-node named 'regulators'. Regulator nodes included in this @@ -71,7 +76,8 @@ Example: compatible = samsung,s2mps11-pmic; reg = 0x66; - s2m_osc: clocks{ + s2m_osc: clocks { + compatible = samsung,s2mps11-clk; #clock-cells = 1; clock-output-names = xx, yy, zz; }; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [U-Boot] ref: virt-v7.c switching to non_secure mode
Hi, We are able to figure out the issue. PERIPHBASE returned on ARNDALE board was 0x1050 and adding GIC offset was creating an incorrect address. please see: https://github.com/apritzel/u-boot-hypmode/commit/5d9c4209907c6d67dadd033887a30c2f10efeb4c Setting CONFIG_ARM_GIC_BASE_ADDRESS as 0x1048 in arndale.h solves the issue. Yes, I spotted that before and deliberately introduced that variable for the Exynos SoCs. The u-boot code needs to be fixed for arndale right ? Please confirm I could get the Arndale to boot with this above patch. But only after a warm reboot: 1) boot the board up, load the kernel and launch it: Linux will reboot very early (before any useful output via earlyprintk) 2) (back in u-boot:) load the kernel again and launch it: works I got both cores in HYP mode and KVM initialized fine. I lost access to my board, so if you could debug this I would be grateful. Thanks, Andre. Regards Manish armdev Team @FTM On 13-Mar-2014, at 11:20 am, armdev armdev@gmail.com wrote: Got a mail that Andre is not with linaro, Adding Christoffer Dall On 13-Mar-2014, at 11:17 am, armdev armdev@gmail.com wrote: Hi Andrey , This is wrt your patch set which enabled the switch to non-sec and hip mode in armv7. We have a small piece of code which we run in hypmode using the bootm command on arndale board While this code was trying to access the GICD_ISENABLR0 (0x10481100), read was always returning 0, while as per the reset value it should be 0x. Debugged more in u-boot and added prints. This is the log, our observation is that in _nonsec_init() there is something that is causing the issue. Now It can be an issue or a gap in our understanding. Ideally we should be able to read the GICD_ISENABLR value as 0x. Can you please help us in find out how to read GIC values properly in hyp mode. armv7_switch_nonsec cpsr =61d3 REGS Before write to group regs cpsr =61d3 REGS Before _nonsec_init() cpsr =61d3 REGS After _nonsec_init() cpsr =61d3 REGS 0 HYP mode: successful. armv7_switch_hyp cpsr =61da REGS 0 Here is the diff of our modifications. (just added prints) diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c index 2cd604f..f38f125 100644 --- a/arch/arm/cpu/armv7/virt-v7.c +++ b/arch/arm/cpu/armv7/virt-v7.c @@ -107,6 +107,10 @@ int armv7_switch_hyp(void) printf(HYP mode: switch not successful.\n); return -1; } + printf(HYP mode: successful.\n); + printf(%s \r\n,__FUNCTION__); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); return 0; } @@ -116,6 +120,10 @@ int armv7_switch_nonsec(void) unsigned int reg; unsigned itlinesnr, i; + printf(%s \r\n,__FUNCTION__); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); + /* check whether the CPU supports the security extensions */ reg = read_id_pfr1(); if ((reg 0xF0) == 0) { @@ -140,6 +148,9 @@ int armv7_switch_nonsec(void) /* TYPER[4:0] contains an encoded number of available interrupts */ itlinesnr = readl(gic_dist_addr + GICD_TYPER) 0x1f; + printf(Before write to group regs \r\n); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); /* set all bits in the GIC group registers to one to allow access * from non-secure state. The first 32 interrupts are private per * CPU and will be set later when enabling the GIC for each core @@ -147,11 +158,19 @@ int armv7_switch_nonsec(void) for (i = 1; i = itlinesnr; i++) writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); - smp_set_core_boot_addr((unsigned long)_smp_pen, -1); - smp_kick_all_cpus(); + //smp_set_core_boot_addr((unsigned long)_smp_pen, -1); + //smp_kick_all_cpus(); + printf(Before _nonsec_init() \r\n); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); /* call the non-sec switching code on this CPU also */ _nonsec_init(); + printf(After _nonsec_init() \r\n); + printf(cpsr =%x\n, read_cpsr()); + printf(REGS %x \n, *(uint32_t*)0x10481100); + + return 0; } diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 515facf..53a1212 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -62,7 +62,6 @@ /* select serial console configuration */ #define CONFIG_BAUDRATE 115200 #define EXYNOS5_DEFAULT_UART_OFFSET 0x01 -#define CONFIG_SILENT_CONSOLE /* Console configuration */ #define CONFIG_CONSOLE_MUX @@ -249,4 +248,7 @@ /* Enable Time Command */ #define CONFIG_CMD_TIME +/* Enable jump to hypervisor */ +#define CONFIG_ARMV7_VIRT +#define CONFIG_SMP_PEN_ADDR 0x0 #endif /* __CONFIG_H */ ___ U-Boot mailing list u-b...@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot -- IMPORTANT NOTICE: The contents of this email and any
Re: [U-Boot] ref: virt-v7.c switching to non_secure mode
Hi, sorry for the double post. Please don't use the Gmail address, this is just my ML catching account. I got a denial from our SMTP server regarding the u-boot ML recipient, so I had to send it again. Thanks, Andre. On 13/03/14 09:29, Reinhard Moselbach wrote: Hi, We are able to figure out the issue. PERIPHBASE returned on ARNDALE board was 0x1050 and adding GIC offset was creating an incorrect address. please see: https://github.com/apritzel/u-boot-hypmode/commit/5d9c4209907c6d67dadd033887a30c2f10efeb4c Setting CONFIG_ARM_GIC_BASE_ADDRESS as 0x1048 in arndale.h solves the issue. Yes, I spotted that before and deliberately introduced that variable for the Exynos SoCs. The u-boot code needs to be fixed for arndale right ? Please confirm I could get the Arndale to boot with this above patch. But only after a warm reboot: 1) boot the board up, load the kernel and launch it: Linux will reboot very early (before any useful output via earlyprintk) 2) (back in u-boot:) load the kernel again and launch it: works I got both cores in HYP mode and KVM initialized fine. I lost access to my board, so if you could debug this I would be grateful. Thanks, Andre. Regards Manish armdev Team @FTM On 13-Mar-2014, at 11:20 am, armdev armdev@gmail.com wrote: Got a mail that Andre is not with linaro, Adding Christoffer Dall On 13-Mar-2014, at 11:17 am, armdev armdev@gmail.com wrote: Hi Andrey , This is wrt your patch set which enabled the switch to non-sec and hip mode in armv7. We have a small piece of code which we run in hypmode using the bootm command on arndale board While this code was trying to access the GICD_ISENABLR0 (0x10481100), read was always returning 0, while as per the reset value it should be 0x. Debugged more in u-boot and added prints. This is the log, our observation is that in _nonsec_init() there is something that is causing the issue. Now It can be an issue or a gap in our understanding. Ideally we should be able to read the GICD_ISENABLR value as 0x. Can you please help us in find out how to read GIC values properly in hyp mode. armv7_switch_nonsec cpsr =61d3 REGS Before write to group regs cpsr =61d3 REGS Before _nonsec_init() cpsr =61d3 REGS After _nonsec_init() cpsr =61d3 REGS 0 HYP mode: successful. armv7_switch_hyp cpsr =61da REGS 0 Here is the diff of our modifications. (just added prints) diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c index 2cd604f..f38f125 100644 --- a/arch/arm/cpu/armv7/virt-v7.c +++ b/arch/arm/cpu/armv7/virt-v7.c @@ -107,6 +107,10 @@ int armv7_switch_hyp(void) printf(HYP mode: switch not successful.\n); return -1; } +printf(HYP mode: successful.\n); +printf(%s \r\n,__FUNCTION__); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); return 0; } @@ -116,6 +120,10 @@ int armv7_switch_nonsec(void) unsigned int reg; unsigned itlinesnr, i; +printf(%s \r\n,__FUNCTION__); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); + /* check whether the CPU supports the security extensions */ reg = read_id_pfr1(); if ((reg 0xF0) == 0) { @@ -140,6 +148,9 @@ int armv7_switch_nonsec(void) /* TYPER[4:0] contains an encoded number of available interrupts */ itlinesnr = readl(gic_dist_addr + GICD_TYPER) 0x1f; +printf(Before write to group regs \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); /* set all bits in the GIC group registers to one to allow access * from non-secure state. The first 32 interrupts are private per * CPU and will be set later when enabling the GIC for each core @@ -147,11 +158,19 @@ int armv7_switch_nonsec(void) for (i = 1; i = itlinesnr; i++) writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); -smp_set_core_boot_addr((unsigned long)_smp_pen, -1); -smp_kick_all_cpus(); +//smp_set_core_boot_addr((unsigned long)_smp_pen, -1); +//smp_kick_all_cpus(); +printf(Before _nonsec_init() \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); /* call the non-sec switching code on this CPU also */ _nonsec_init(); +printf(After _nonsec_init() \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); + + return 0; } diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 515facf..53a1212 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -62,7 +62,6 @@ /* select serial console configuration */ #define CONFIG_BAUDRATE115200 #define EXYNOS5_DEFAULT_UART_OFFSET0x01 -#define CONFIG_SILENT_CONSOLE /* Console configuration */ #define CONFIG_CONSOLE_MUX @@ -249,4 +248,7 @@ /* Enable Time Command */ #define CONFIG_CMD_TIME +/* Enable jump to hypervisor */ +#define
Re: [PATCH v5 3/5] clk/samsung: add support for pll2650xx
On Thu, Mar 13, 2014 at 10:28 AM, Pankaj Dubey pankaj.du...@samsung.com wrote: Hi Rahul, On 03/12/2014 11:56 PM, Rahul Sharma wrote: Add support for pll2650xx in samsung pll file. This PLL variant is close to pll36xx but uses CON2 registers instead of CON1. Aud_pll in Exynos5260 is pll2650xx and uses this code. Signed-off-by: Rahul Sharma rahul.sha...@samsung.com --- drivers/clk/samsung/clk-pll.c | 101 + drivers/clk/samsung/clk-pll.h |1 + 2 files changed, 102 insertions(+) diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 18e42ef..b07fad2 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -1049,6 +1049,101 @@ static const struct clk_ops samsung_pll2550xx_clk_min_ops = { .recalc_rate = samsung_pll2550xx_recalc_rate, }; +/* + * PLL2650XX Clock Type + */ + +/* Maximum lock time can be 3000 * PDIV cycles */ +#define PLL2650XX_LOCK_FACTOR 3000 + +#define PLL2650XX_MDIV_SHIFT 9 +#define PLL2650XX_PDIV_SHIFT 3 +#define PLL2650XX_SDIV_SHIFT 0 +#define PLL2650XX_KDIV_SHIFT 0 +#define PLL2650XX_MDIV_MASK0x1ff +#define PLL2650XX_PDIV_MASK0x3f +#define PLL2650XX_SDIV_MASK0x7 +#define PLL2650XX_KDIV_MASK0x +#define PLL2650XX_PLL_ENABLE_SHIFT 23 +#define PLL2650XX_PLL_LOCKTIME_SHIFT 21 +#define PLL2650XX_PLL_FOUTMASK_SHIFT 31 + +static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 mdiv, pdiv, sdiv, pll_con0, pll_con2; + s16 kdiv; + u64 fvco = parent_rate; + + pll_con0 = __raw_readl(pll-con_reg); + pll_con2 = __raw_readl(pll-con_reg + 8); + mdiv = (pll_con0 PLL2650XX_MDIV_SHIFT) PLL2650XX_MDIV_MASK; + pdiv = (pll_con0 PLL2650XX_PDIV_SHIFT) PLL2650XX_PDIV_MASK; + sdiv = (pll_con0 PLL2650XX_SDIV_SHIFT) PLL2650XX_SDIV_MASK; + kdiv = (s16)(pll_con2 PLL2650XX_KDIV_MASK); + + fvco *= (mdiv 16) + kdiv; + do_div(fvco, (pdiv sdiv)); + fvco = 16; + + return (unsigned long)fvco; +} + +static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 tmp, pll_con0, pll_con2; + const struct samsung_pll_rate_table *rate; + + rate = samsung_get_pll_settings(pll, drate); + if (!rate) { + pr_err(%s: Invalid rate : %lu for pll clk %s\n, __func__, + drate, __clk_get_name(hw-clk)); + return -EINVAL; + } + + pll_con0 = __raw_readl(pll-con_reg); + pll_con2 = __raw_readl(pll-con_reg + 8); + +/* Change PLL PMS values */ + pll_con0 = ~(PLL2650XX_MDIV_MASK PLL2650XX_MDIV_SHIFT | + PLL2650XX_PDIV_MASK PLL2650XX_PDIV_SHIFT | + PLL2650XX_SDIV_MASK PLL2650XX_SDIV_SHIFT); + pll_con0 |= rate-mdiv PLL2650XX_MDIV_SHIFT; + pll_con0 |= rate-pdiv PLL2650XX_PDIV_SHIFT; + pll_con0 |= rate-sdiv PLL2650XX_SDIV_SHIFT; + pll_con0 |= 1 PLL2650XX_PLL_ENABLE_SHIFT; + pll_con0 |= 1 PLL2650XX_PLL_FOUTMASK_SHIFT; + + pll_con2 = ~(PLL2650XX_KDIV_MASK PLL2650XX_KDIV_SHIFT); + pll_con2 |= ((~(rate-kdiv) + 1) PLL2650XX_KDIV_MASK) +PLL2650XX_KDIV_SHIFT; + + /* Set PLL lock time. */ + __raw_writel(PLL2650XX_LOCK_FACTOR * rate-pdiv, pll-lock_reg); + + __raw_writel(pll_con0, pll-con_reg); + __raw_writel(pll_con2, pll-con_reg + 8); + + do { + tmp = __raw_readl(pll-con_reg); + } while (!(tmp (0x1 PLL2650XX_PLL_LOCKTIME_SHIFT))); + + return 0; +} + +static const struct clk_ops samsung_pll2650xx_clk_ops = { + .recalc_rate = samsung_pll2650xx_recalc_rate, + .set_rate = samsung_pll2650xx_set_rate, + .round_rate = samsung_pll_round_rate, +}; + +static const struct clk_ops samsung_pll2650xx_clk_min_ops = { + .recalc_rate = samsung_pll2650xx_recalc_rate, +}; + static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, struct samsung_pll_clock *pll_clk, void __iomem *base) @@ -1157,6 +1252,12 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = samsung_pll2550xx_clk_ops; break; + case pll_2650xx: + if (!pll-rate_table) + init.ops = samsung_pll2650xx_clk_min_ops; + else + init.ops = samsung_pll2650xx_clk_ops;
Re: [PATCH v2 1/3] arm64: dts: add initial dts for Samsung GH7 SoC and SSDK-GH7 board
On Wed, Mar 12, 2014 at 04:31:56AM +, Kukjin Kim wrote: Mark Rutland wrote: Hi Mark, On Mon, Mar 10, 2014 at 10:51:17PM +, Kukjin Kim wrote: Signed-off-by: Kukjin Kim kgene@samsung.com Reviewed-by: Thomas Abraham thomas...@samsung.com Cc: Catalin Marinas catalin.mari...@arm.com --- arch/arm64/boot/dts/samsung-gh7.dtsi | 106 +++ arch/arm64/boot/dts/samsung-ssdk-gh7.dts | 26 2 files changed, 132 insertions(+) create mode 100644 arch/arm64/boot/dts/samsung-gh7.dtsi create mode 100644 arch/arm64/boot/dts/samsung-ssdk-gh7.dts diff --git a/arch/arm64/boot/dts/samsung-gh7.dtsi b/arch/arm64/boot/dts/samsung-gh7.dtsi new file mode 100644 index 000..b5e8488 --- /dev/null +++ b/arch/arm64/boot/dts/samsung-gh7.dtsi @@ -0,0 +1,106 @@ +/* + * SAMSUNG GH7 SoC device tree source + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/memreserve/ 0x8000 0x0C40; Please have a comment as to what this memreserve is intended to protect. This is very large, and we don't want pointless memreserves. Well, you mean I need to comment about each reserved memory area? Please have a comment about what each /memreserve/ is intended to protect. We need the reserved memory for EL3 monitor, UEFI services, secure interpreter, hypervisor and Scan-chain for debug...BTW isn't it depending on each hardware platform and usage model? If it depends on each particular model then it doesn't belong in the shared dtsi, and each dts should have the /memreserve/ for that platform. Why would the hypervisor or secure OS memory ever be accessible to the kernel such that it would require a memreserve? That sounds fundamentally broken. I was under the impression that if using UEFI we can identify and reserve the UEFI services by walking to UEFI memory map. If we don't use them, they don't need to be protected. As such, I don't see why they need a memreserve for them. Just note, I will change the reserve memory area and size. From at 0xf800 and size is 128MB(0x800). Ok. What address does the kernel end up getting loaded at on this board? We load the kernel image from at 0x8008 after changing the reserve memory area. Ok. +/ { + interrupt-parent = gic; + #address-cells = 2; + #size-cells = 2; + + aliases { + serial0 = /amba/uart@12c0; + }; + + cpus { + #address-cells = 2; + #size-cells = 0; + + cpu@000 { + device_type = cpu; + compatible = arm,armv8; The arm,armv8 should be a fallback rather than the only entry. The precise core should be first (see arch/arm64/boot/dts/apm-storm.dtsi for an example). Well, do I really need another name if GH7 has just 'ARMv8 core' exactly? Yes please. You presumably don't have just 'ARMv8 core', but rather a specific ARMv8 implementation. + reg = 0x0 0x000; Any reason for padding these to three hexadecimal digits (in both the reg and unit-address)? Yes, I already commented on Olof's question before, other cores will be added and it should be separated from this. Ok. + enable-method = spin-table; + cpu-release-addr = 0x0 0x8000fff8; + }; + cpu@001 { + device_type = cpu; + compatible = arm,armv8; + reg = 0x0 0x001; + enable-method = spin-table; + cpu-release-addr = 0x0 0x8000fff8; + }; + cpu@002 { + device_type = cpu; + compatible = arm,armv8; + reg = 0x0 0x002; + enable-method = spin-table; + cpu-release-addr = 0x0 0x8000fff8; + }; + cpu@003 { + device_type = cpu; + compatible = arm,armv8; + reg = 0x0 0x003; + enable-method = spin-table; + cpu-release-addr = 0x0 0x8000fff8; + }; + }; + + gic: interrupt-controller@1C00 { + compatible = arm,cortex-a15-gic; We should have a more specific compatible string early in the list here too. Well, I think more specific compatible string is not required for gic, there were discussion about using another compatible string for gic-v2. And cortex-a15-gic should be fine at this moment and if another name is required as per previous discussion, we will then. While it's probably ok to have arm,cortex-a15-gic in the compatible list, it would be good to also
Re: [U-Boot] ref: virt-v7.c switching to non_secure mode
On 13-Mar-2014, at 3:57 pm, Andre Przywara andre.przyw...@arm.com wrote: Hi, sorry for the double post. Please don't use the Gmail address, this is just my ML catching account. I got a denial from our SMTP server regarding the u-boot ML recipient, so I had to send it again. We are using google services gmail for all external mailing lists. Thanks, Andre. On 13/03/14 09:29, Reinhard Moselbach wrote: Hi, We are able to figure out the issue. PERIPHBASE returned on ARNDALE board was 0x1050 and adding GIC offset was creating an incorrect address. please see: https://github.com/apritzel/u-boot-hypmode/commit/5d9c4209907c6d67dadd033887a30c2f10efeb4c Setting CONFIG_ARM_GIC_BASE_ADDRESS as 0x1048 in arndale.h solves the issue. Yes, I spotted that before and deliberately introduced that variable for the Exynos SoCs. The u-boot code needs to be fixed for arndale right ? Please confirm I could get the Arndale to boot with this above patch. But only after a warm reboot: 1) boot the board up, load the kernel and launch it: Linux will reboot very early (before any useful output via earlyprintk) 2) (back in u-boot:) load the kernel again and launch it: works I got both cores in HYP mode and KVM initialized fine. I lost access to my board, so if you could debug this I would be grateful. Thanks, Andre. Regards Manish armdev Team @FTM On 13-Mar-2014, at 11:20 am, armdev armdev@gmail.com wrote: Got a mail that Andre is not with linaro, Adding Christoffer Dall On 13-Mar-2014, at 11:17 am, armdev armdev@gmail.com wrote: Hi Andrey , This is wrt your patch set which enabled the switch to non-sec and hip mode in armv7. We have a small piece of code which we run in hypmode using the bootm command on arndale board While this code was trying to access the GICD_ISENABLR0 (0x10481100), read was always returning 0, while as per the reset value it should be 0x. Debugged more in u-boot and added prints. This is the log, our observation is that in _nonsec_init() there is something that is causing the issue. Now It can be an issue or a gap in our understanding. Ideally we should be able to read the GICD_ISENABLR value as 0x. Can you please help us in find out how to read GIC values properly in hyp mode. armv7_switch_nonsec cpsr =61d3 REGS Before write to group regs cpsr =61d3 REGS Before _nonsec_init() cpsr =61d3 REGS After _nonsec_init() cpsr =61d3 REGS 0 HYP mode: successful. armv7_switch_hyp cpsr =61da REGS 0 Here is the diff of our modifications. (just added prints) diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c index 2cd604f..f38f125 100644 --- a/arch/arm/cpu/armv7/virt-v7.c +++ b/arch/arm/cpu/armv7/virt-v7.c @@ -107,6 +107,10 @@ int armv7_switch_hyp(void) printf(HYP mode: switch not successful.\n); return -1; } +printf(HYP mode: successful.\n); +printf(%s \r\n,__FUNCTION__); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); return 0; } @@ -116,6 +120,10 @@ int armv7_switch_nonsec(void) unsigned int reg; unsigned itlinesnr, i; +printf(%s \r\n,__FUNCTION__); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); + /* check whether the CPU supports the security extensions */ reg = read_id_pfr1(); if ((reg 0xF0) == 0) { @@ -140,6 +148,9 @@ int armv7_switch_nonsec(void) /* TYPER[4:0] contains an encoded number of available interrupts */ itlinesnr = readl(gic_dist_addr + GICD_TYPER) 0x1f; +printf(Before write to group regs \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); /* set all bits in the GIC group registers to one to allow access * from non-secure state. The first 32 interrupts are private per * CPU and will be set later when enabling the GIC for each core @@ -147,11 +158,19 @@ int armv7_switch_nonsec(void) for (i = 1; i = itlinesnr; i++) writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); -smp_set_core_boot_addr((unsigned long)_smp_pen, -1); -smp_kick_all_cpus(); +//smp_set_core_boot_addr((unsigned long)_smp_pen, -1); +//smp_kick_all_cpus(); +printf(Before _nonsec_init() \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); /* call the non-sec switching code on this CPU also */ _nonsec_init(); +printf(After _nonsec_init() \r\n); +printf(cpsr =%x\n, read_cpsr()); +printf(REGS %x \n, *(uint32_t*)0x10481100); + + return 0; } diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 515facf..53a1212 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -62,7 +62,6 @@ /* select serial console configuration */ #define CONFIG_BAUDRATE
Re: [PATCH 1/1] clk: exynos-5420: Fix VPLL lock offset
Hi Sachin, On 13.03.2014 04:27, Sachin Kamat wrote: Set it as per the user manual. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/clk/samsung/clk-exynos5420.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 60b26819bed5..7fd6bea467fd 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -33,7 +33,7 @@ #define RPLL_LOCK 0x10050 #define IPLL_LOCK 0x10060 #define SPLL_LOCK 0x10070 -#define VPLL_LOCK 0x10070 +#define VPLL_LOCK 0x10080 #define MPLL_LOCK 0x10090 #define CPLL_CON0 0x10120 #define DPLL_CON0 0x10128 Looks fine. Will queue for 3.15, since ATM there is no support for PLL rate setting on Exynos 5420 (no rate tables registered). Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/3] mfd: sec-core: Add of_compatible strings for MFD cells
Hi Krzysztof, On 13.03.2014 10:37, Krzysztof Kozlowski wrote: Add of_compatible strings for MFD cells for regulator, clock and RTC drivers in S5M8767, S2MPS11 and S2MPS14 PMIC-s. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com --- drivers/mfd/sec-core.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index d163c66edebb..c5b9b95b2099 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -55,28 +55,36 @@ static const struct mfd_cell s5m8763_devs[] = { static const struct mfd_cell s5m8767_devs[] = { { .name = s5m8767-pmic, + .of_compatible = samsung,s5m8767-regulators, }, { .name = s5m-rtc, + .of_compatible = samsung,s5m8767-rtc, }, { .name = s5m8767-clk, + .of_compatible = samsung,s5m8767-clk, } }; static const struct mfd_cell s2mps11_devs[] = { { .name = s2mps11-pmic, + .of_compatible = samsung,s2mps11-regulators, }, { .name = s2mps11-clk, + .of_compatible = samsung,s2mps11-clk, } }; static const struct mfd_cell s2mps14_devs[] = { { .name = s2mps14-pmic, + .of_compatible = samsung,s2mps14-regulators, }, { .name = s2mps14-rtc, + .of_compatible = samsung,s2mps14-rtc, }, { .name = s2mps14-clk, + .of_compatible = samsung,s2mps14-clk, } }; Are these compatible strings documented anywhere? Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/3] mfd: sec-core: Add of_compatible strings for MFD cells
On Thu, 2014-03-13 at 13:07 +0100, Tomasz Figa wrote: Hi Krzysztof, On 13.03.2014 10:37, Krzysztof Kozlowski wrote: Add of_compatible strings for MFD cells for regulator, clock and RTC drivers in S5M8767, S2MPS11 and S2MPS14 PMIC-s. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com --- drivers/mfd/sec-core.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index d163c66edebb..c5b9b95b2099 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -55,28 +55,36 @@ static const struct mfd_cell s5m8763_devs[] = { static const struct mfd_cell s5m8767_devs[] = { { .name = s5m8767-pmic, + .of_compatible = samsung,s5m8767-regulators, }, { .name = s5m-rtc, + .of_compatible = samsung,s5m8767-rtc, }, { .name = s5m8767-clk, + .of_compatible = samsung,s5m8767-clk, } }; static const struct mfd_cell s2mps11_devs[] = { { .name = s2mps11-pmic, + .of_compatible = samsung,s2mps11-regulators, }, { .name = s2mps11-clk, + .of_compatible = samsung,s2mps11-clk, } }; static const struct mfd_cell s2mps14_devs[] = { { .name = s2mps14-pmic, + .of_compatible = samsung,s2mps14-regulators, }, { .name = s2mps14-rtc, + .of_compatible = samsung,s2mps14-rtc, }, { .name = s2mps14-clk, + .of_compatible = samsung,s2mps14-clk, } }; Are these compatible strings documented anywhere? The -clk compatible strings are (in next patch). The -rtc and -regulators are not. Actually they aren't also used by child driver (each child driver parses from parent of_node). Best regards, Krzysztof -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 4/5] clk/exynos5260: add macros and documentation for exynos5260
Hi Rahul, On 12.03.2014 15:56, Rahul Sharma wrote: Add macros which are used as Clock IDs in DT and clock file. It also adds the documentation for the exynos5260 clocks. Signed-off-by: Rahul Sharma rahul.sha...@samsung.com --- .../devicetree/bindings/clock/exynos5260-clock.txt | 55 + include/dt-bindings/clock/exynos5260-clk.h | 233 2 files changed, 288 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/exynos5260-clock.txt create mode 100644 include/dt-bindings/clock/exynos5260-clk.h diff --git a/Documentation/devicetree/bindings/clock/exynos5260-clock.txt b/Documentation/devicetree/bindings/clock/exynos5260-clock.txt new file mode 100644 index 000..4128892 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/exynos5260-clock.txt @@ -0,0 +1,55 @@ +* Samsung Exynos5260 Clock Controller + +The Exynos5260 clock controller encapsulate all CMUs which are s/encapsulate/encapsulates/ Anyway, I don't think there is any global clock controller entity that should be described here. The binding is related to several separate entities found on Exynos5260, i.e. particular CMUs. +instantiaited independently from the device-tree. As a whole, these s/instantiaited/instantiated/ s/the device-tree/device tree/ +CMUs generates and supplies clocks to various controllers within s/generates/generate/ s/supplies/supply/ +the Exynos5260 SoC. + +Required Properties: + +- compatible: should be one of the following. + exynos5260-clock-top + exynos5260-clock-peri + exynos5260-clock-egl + exynos5260-clock-kfc + exynos5260-clock-g2d + exynos5260-clock-mif + exynos5260-clock-mfc + exynos5260-clock-g3d + exynos5260-clock-fsys + exynos5260-clock-aud + exynos5260-clock-isp + exynos5260-clock-gscl + exynos5260-clock-disp Compatible strings should be prefixed with Samsung's vendor prefix, i.e. samsung,. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. As implemented in patch [1] the clock core will be able to sort out dependencies between particular clock providers based on clock consumer bindings. This means that it would be a good idea to add clock properties to this binding and strictly specify which clocks outside particular CMU block are fed into the block. So for example, if CMU TOP uses fin_pll clock, its node would need to have clock-names property with fin_pll entry and clocks property with respective entry pointing to the fixed rate clock node. In general, all external, IO and PHY clocks fed into CMU blocks should be listed this way to have dependencies between clocks properly defined in the system. [1] http://thread.gmane.org/gmane.linux.kernel/1654635 + +The following is the list of clocks generated by each controller. There is no list below. IMHO this sentence should be removed. Each +clock is assigned with a MACRO constant. These constants are defined in +dt-bindings/clk/exynos5260-clk.h. DT client nodes use this MACRO to +specify the clock, which they want to consume. IMHO the whole paragraph above can be rewritten taking samsung,s3c64xx-clock.txt as an example: Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. All available clocks are defined as preprocessor macros in dt-bindings/clock/exynos5260-clk.h header and can be used in device tree sources. In addition to the above, a list of external clocks that need or may be present should be added. Again, see samsung,s3c64xx-clock.txt for an example. + +Example 1: An example of a clock controller node is listed below. + + cmu_disp: clock-controller@0x1455 { + compatible = exynos5260-clock-disp; Incorrect compatible string. + reg = 0x1455 0x1; + #clock-cells = 1; + }; + +Example 2: UART controller node that consumes the clock generated by the + peri clock controller. Refer to the standard clock bindings for + information about 'clocks' and 'clock-names' property. + + serial@12C0 { + compatible = samsung,exynos4210-uart; + reg = 0x12C0 0x100; + interrupts = 0 146 0; + clocks = clock_peri PERI_PCLK_UART0, clock_peri PERI_SCLK_UART0; + clock-names = uart, clk_uart_baud0; + status = disabled; + }; + diff --git a/include/dt-bindings/clock/exynos5260-clk.h b/include/dt-bindings/clock/exynos5260-clk.h new file mode 100644 index 000..d6f4391 --- /dev/null +++ b/include/dt-bindings/clock/exynos5260-clk.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + *
Re: [PATCH v2 2/3] mfd: sec-core: Add of_compatible strings for MFD cells
On 13.03.2014 13:16, Krzysztof Kozlowski wrote: On Thu, 2014-03-13 at 13:07 +0100, Tomasz Figa wrote: Hi Krzysztof, On 13.03.2014 10:37, Krzysztof Kozlowski wrote: Add of_compatible strings for MFD cells for regulator, clock and RTC drivers in S5M8767, S2MPS11 and S2MPS14 PMIC-s. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com --- drivers/mfd/sec-core.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index d163c66edebb..c5b9b95b2099 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -55,28 +55,36 @@ static const struct mfd_cell s5m8763_devs[] = { static const struct mfd_cell s5m8767_devs[] = { { .name = s5m8767-pmic, + .of_compatible = samsung,s5m8767-regulators, }, { .name = s5m-rtc, + .of_compatible = samsung,s5m8767-rtc, }, { .name = s5m8767-clk, + .of_compatible = samsung,s5m8767-clk, } }; static const struct mfd_cell s2mps11_devs[] = { { .name = s2mps11-pmic, + .of_compatible = samsung,s2mps11-regulators, }, { .name = s2mps11-clk, + .of_compatible = samsung,s2mps11-clk, } }; static const struct mfd_cell s2mps14_devs[] = { { .name = s2mps14-pmic, + .of_compatible = samsung,s2mps14-regulators, }, { .name = s2mps14-rtc, + .of_compatible = samsung,s2mps14-rtc, }, { .name = s2mps14-clk, + .of_compatible = samsung,s2mps14-clk, } }; Are these compatible strings documented anywhere? The -clk compatible strings are (in next patch). The -rtc and -regulators are not. Hmm, this doesn't sound good. Actually they aren't also used by child driver (each child driver parses from parent of_node). Do you need to add compatible strings to mfd_cell entries of such cells then? Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/3] mfd: sec-core: Add of_compatible strings for MFD cells
On Thu, 2014-03-13 at 13:37 +0100, Tomasz Figa wrote: On 13.03.2014 13:16, Krzysztof Kozlowski wrote: On Thu, 2014-03-13 at 13:07 +0100, Tomasz Figa wrote: Hi Krzysztof, On 13.03.2014 10:37, Krzysztof Kozlowski wrote: Add of_compatible strings for MFD cells for regulator, clock and RTC drivers in S5M8767, S2MPS11 and S2MPS14 PMIC-s. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com --- drivers/mfd/sec-core.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index d163c66edebb..c5b9b95b2099 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -55,28 +55,36 @@ static const struct mfd_cell s5m8763_devs[] = { static const struct mfd_cell s5m8767_devs[] = { { .name = s5m8767-pmic, + .of_compatible = samsung,s5m8767-regulators, }, { .name = s5m-rtc, + .of_compatible = samsung,s5m8767-rtc, }, { .name = s5m8767-clk, + .of_compatible = samsung,s5m8767-clk, } }; static const struct mfd_cell s2mps11_devs[] = { { .name = s2mps11-pmic, + .of_compatible = samsung,s2mps11-regulators, }, { .name = s2mps11-clk, + .of_compatible = samsung,s2mps11-clk, } }; static const struct mfd_cell s2mps14_devs[] = { { .name = s2mps14-pmic, + .of_compatible = samsung,s2mps14-regulators, }, { .name = s2mps14-rtc, + .of_compatible = samsung,s2mps14-rtc, }, { .name = s2mps14-clk, + .of_compatible = samsung,s2mps14-clk, } }; Are these compatible strings documented anywhere? The -clk compatible strings are (in next patch). The -rtc and -regulators are not. Hmm, this doesn't sound good. Actually they aren't also used by child driver (each child driver parses from parent of_node). Do you need to add compatible strings to mfd_cell entries of such cells then? From my point of view there isn't any special need for them (except for clk). Dear Lee, Do you wish to have these compatibles for all of child drivers even when they aren't used directly by them? If yes then probably I should document them. Best regards, Krzysztof -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] Documentation: mfd: s2mps11: Describe S5M8767 and S2MPS14 clocks
Hi Krzysztof, On 13.03.2014 10:37, Krzysztof Kozlowski wrote: Add bindings documentation for clocks on S5M8767 and S2MPS14 devices. Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com Cc: Tomasz Figa t.f...@samsung.com Cc: devicet...@vger.kernel.org Cc: Rob Herring robh...@kernel.org Cc: Pawel Moll pawel.m...@arm.com Cc: Mark Rutland mark.rutl...@arm.com Cc: Ian Campbell ijc+devicet...@hellion.org.uk Cc: Kumar Gala ga...@codeaurora.org --- Documentation/devicetree/bindings/mfd/s2mps11.txt | 24 + 1 file changed, 15 insertions(+), 9 deletions(-) Reviewed-by: Tomasz Figa t.f...@samsung.com Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 RE-SEND 1/7] net: sxgbe: add basic framework for Samsung 10Gb ethernet driver
On Thu, 2014-03-13 at 15:55 +0900, Byungho An wrote: This patch adds support for Samsung 10Gb ethernet driver(sxgbe). - sxgbe core initialization - Tx and Rx support - MDIO support - ISRs for Tx and Rx - ifconfig support to driver [] diff --git a/drivers/net/ethernet/samsung/sxgbe_desc.c b/drivers/net/ethernet/samsung/sxgbe_desc.c [] +/* Set Time stamp */ +static void sxgbe_tx_ctxt_desc_set_tstamp(struct sxgbe_tx_ctxt_desc *p, + u8 ostc_enable, u64 tstamp) +{ + if (ostc_enable) { + p-ostc = ostc_enable; + p-tstamp_lo = (u32) tstamp; + p-tstamp_hi = (u32) (tstamp32); + } +} [] +static u64 sxgbe_get_rx_timestamp(struct sxgbe_rx_ctxt_desc *p) +{ + u64 ns; + ns = p-tstamp_lo; + ns += p-tstamp_hi * 10ULL; + + return ns; +} This looks odd. rx and tx timestamps are different clocks? rx tstamp_lo resets every second but tx_stamp is free-running? Maybe this was supposed to be something like ns = p-tstamp_lo ns |= ((u64)tstamp_hi) 32; If not, maybe it warrants a comment around here or on the descriptor definition diff --git a/drivers/net/ethernet/samsung/sxgbe_desc.h b/drivers/net/ethernet/samsung/sxgbe_desc.h [] +/* Context descriptor structure */ +struct sxgbe_tx_ctxt_desc { + u32 tstamp_lo:32; + u32 tstamp_hi:32; [] +struct sxgbe_rx_ctxt_desc { + u32 tstamp_lo:32; + u32 tstamp_hi:32; -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 RE-SEND 1/7] net: sxgbe: add basic framework for Samsung 10Gb ethernet driver
On Thu, 2014-03-13 at 05:53 -0700, Joe Perches wrote: Maybe this was supposed to be something like ns = p-tstamp_lo ns |= ((u64)tstamp_hi) 32; If not, maybe it warrants a comment around here or on the descriptor definition [] +struct sxgbe_rx_ctxt_desc { + u32 tstamp_lo:32; + u32 tstamp_hi:32; or maybe these would be better renamed like: u32 tstamp_nsecs; u32 tstamp_secs; btw2: I still think using u32 foo:32; is asking for gcc to generate bad code. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/3] mfd: sec-core: Add of_compatible strings for MFD cells
snip Are these compatible strings documented anywhere? The -clk compatible strings are (in next patch). The -rtc and -regulators are not. Hmm, this doesn't sound good. Actually they aren't also used by child driver (each child driver parses from parent of_node). Do you need to add compatible strings to mfd_cell entries of such cells then? From my point of view there isn't any special need for them (except for clk). Dear Lee, Do you wish to have these compatibles for all of child drivers even when they aren't used directly by them? If yes then probably I should document them. It's your call, either remove the unused ones or document them all. I don't really mind either way. In the previous version I asked if there was any reason why you weren't applying compatible strings to the other cells; subordinate drivers don't use them is a perfectly reasonable reason. -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 5/5] clk/exynos5260: add clock file for exynos5260
On 12.03.2014 15:56, Rahul Sharma wrote: Add support for exynos5260 clocks in clock driver. Signed-off-by: Rahul Sharma rahul.sha...@samsung.com Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com --- drivers/clk/samsung/Makefile |1 + drivers/clk/samsung/clk-exynos5260.c | 1805 ++ drivers/clk/samsung/clk-exynos5260.h | 448 + 3 files changed, 2254 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5260.c create mode 100644 drivers/clk/samsung/clk-exynos5260.h [snip] diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c new file mode 100644 index 000..f72ad6a --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5260.c [snip] +struct samsung_gate_clock aud_gate_clks[] __initdata = { + GATE(AUD_CLK_AUD_UART, clk_aud_uart, dout_aclk_aud_131, + EN_IP_AUD, 4, 0, 0), + GATE(AUD_CLK_PCM, clk_pcm, dout_aclk_aud_131, EN_IP_AUD, 3, 0, 0), + GATE(AUD_CLK_I2S, clk_i2s, dout_aclk_aud_131, EN_IP_AUD, 2, 0, 0), + GATE(AUD_CLK_DMAC, clk_dmac, dout_aclk_aud_131, + EN_IP_AUD, 1, 0, 0), + GATE(0, clk_sramc, dout_aclk_aud_131, EN_IP_AUD, 0, 0, 0), + + GATE(AUD_SCLK_AUD_UART, sclk_aud_uart, dout_sclk_aud_uart, + EN_SCLK_AUD, 2, CLK_SET_RATE_PARENT, 0), + GATE(AUD_SCLK_PCM, sclk_aud_pcm, dout_sclk_aud_pcm, + EN_SCLK_AUD, 1, CLK_SET_RATE_PARENT, 0), + GATE(AUD_SCLK_I2S, sclk_aud_i2s, dout_sclk_aud_i2s, + EN_SCLK_AUD, 0, CLK_SET_RATE_PARENT, 0), Please keep the clocks sorted by the register offsets ascending as well, to match the order in UM. [snip] + +struct samsung_mux_clock disp_mux_clks[] __initdata = { + MUX(0, mout_sclk_hdmi_spdif, mout_sclk_hdmi_spdif_p, + MUX_SEL_DISP4, 4, 2), + + MUX(0, mout_sclk_dsim1_tx_clk_esc_clk_user, + mout_sclk_dsim1_tx_clk_esc_clk_user_p, + MUX_SEL_DISP2, 28, 1), Ditto. [snip] +struct samsung_gate_clock disp_gate_clks[] __initdata = { + GATE(DISP_CLK_SMMU_TV, clk_smmu3_tv, mout_aclk_disp_222_user, + EN_IP_DISP, 25, 0, 0), + GATE(DISP_CLK_SMMU_FIMD1M1, clk_smmu3_fimd1m1, + mout_aclk_disp_222_user, + EN_IP_DISP, 23, 0, 0), + GATE(DISP_CLK_SMMU_FIMD1M0, clk_smmu3_fimd1m0, + mout_aclk_disp_222_user, + EN_IP_DISP, 22, 0, 0), + GATE(0, clk_pixel_mixer, mout_aclk_disp_222_user, + EN_IP_DISP, 13, CLK_IGNORE_UNUSED, 0), + GATE(0, clk_pixel_disp, mout_aclk_disp_222_user, + EN_IP_DISP, 12, CLK_IGNORE_UNUSED, 0), + GATE(DISP_CLK_MIXER, clk_mixer, mout_aclk_disp_222_user, + EN_IP_DISP, 11, 0, 0), + GATE(DISP_CLK_MIPIPHY, clk_mipi_dphy, mout_aclk_disp_222_user, + EN_IP_DISP, 10, 0, 0), + GATE(DISP_CLK_HDMIPHY, clk_hdmiphy, mout_aclk_disp_222_user, + EN_IP_DISP, 9, 0, 0), + GATE(DISP_CLK_HDMI, clk_hdmi, mout_aclk_disp_222_user, + EN_IP_DISP, 8, 0, 0), + GATE(DISP_CLK_FIMD1, clk_fimd1, mout_aclk_disp_222_user, + EN_IP_DISP, 7, 0, 0), + GATE(DISP_CLK_DSIM1, clk_dsim1, mout_aclk_disp_222_user, + EN_IP_DISP, 6, 0, 0), + GATE(DISP_CLK_DPPHY, clk_dptx_phy, mout_aclk_disp_222_user, + EN_IP_DISP, 5, 0, 0), + GATE(DISP_CLK_DP, clk_dptx_link, mout_aclk_disp_222_user, + EN_IP_DISP, 4, 0, 0), + GATE(DISP_SCLK_PIXEL, sclk_hdmi_phy_pixel_clki, + dout_sclk_hdmi_phy_pixel_clki, + EN_SCLK_DISP0, 29, CLK_SET_RATE_PARENT, 0), + GATE(DISP_MOUT_HDMI_PHY_PIXEL_USER, sclk_hdmi_link_i_pixel, + mout_phyclk_hdmi_phy_pixel_clko_user, + EN_SCLK_DISP0, 26, CLK_SET_RATE_PARENT, 0), Ditto. [snip] +struct samsung_gate_clock fsys_gate_clks[] __initdata = { + GATE(FSYS_CLK_TSI, clk_tsi, dout_aclk_fsys_200, + EN_IP_FSYS, 20, 0, 0), + GATE(FSYS_CLK_USBLINK, clk_usblink, dout_aclk_fsys_200, + EN_IP_FSYS, 18, 0, 0), + GATE(FSYS_CLK_USBHOST20, clk_usbhost20, dout_aclk_fsys_200, + EN_IP_FSYS, 15, 0, 0), + GATE(FSYS_CLK_USBDRD30, clk_usbdrd30, dout_aclk_fsys_200, + EN_IP_FSYS, 14, 0, 0), + GATE(FSYS_CLK_SROMC, clk_sromc, dout_aclk_fsys_200, + EN_IP_FSYS, 13, 0, 0), + GATE(FSYS_CLK_PDMA, clk_pdma, dout_aclk_fsys_200, + EN_IP_FSYS, 9, 0, 0), + GATE(FSYS_CLK_MMC2, clk_mmc2, dout_aclk_fsys_200, + EN_IP_FSYS, 8, 0, 0), + GATE(FSYS_CLK_MMC1, clk_mmc1, dout_aclk_fsys_200, +
Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
On 03/13/2014 08:08 AM, Inki Dae wrote: 2014-03-12 20:16 GMT+09:00 Tomasz Figa t.f...@samsung.com: On 12.03.2014 11:08, Inki Dae wrote: 2014-03-07 19:00 GMT+09:00 Andrzej Hajda a.ha...@samsung.com: On 03/05/2014 03:56 AM, Inki Dae wrote: Hi Andrzej, Thanks for your contributions. 2014-02-12 20:31 GMT+09:00 Andrzej Hajda a.ha...@samsung.com: Hi, This patchset adds drivers and bindings to the following devices: - Exynos DSI master, - S6E8AA0 DSI panel, - TC358764 DSI/LVDS bridge, - HV070WSA-100 LVDS panel. It adds also display support in DTS files for the following boards: - Exynos4210/Trats, - Exynos4412/Trats2, - Exynos5250/Arndale. Things worth mentioning: 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie. the driver exposes drm_panel interface on DSI side, and interact with panels on LVDS side using drm_panel framework. This approach seems to me simpler and more natural than using drm_bridge. Can you give me more details about why you think better to use panel framework than using drm_bridge? Simpler and more natural are ambiguous to me. In this particular case DSI master expects on the other end any device having DSI slave interface, it could be panel or bridge. So it seems natural that both types of slave devices should expose the same interface also on programming level. Another problem with drm_bridge is that it is not scalable - if some manufacturer will decide to add another block between the bridge and the panel there is no drm component which can be used for it. Using drm_panel the way I have used in toshiba bridge makes scalability possible, it will be only a matter of adding a driver for new block and making proper links in device tree, I see no easy way of doing it with drm_bridge approach. Now drm_bridge may not cover all hardware. However drm_bridge has already been merged to mainline so I think we need to use drm_bridge somehow instead of using other one, and also we could extend drm_bridge if needed. It would be definitely impossible for a new framework to cover all hardware because there may be other hardware not appeared yet. That is what we are doing for mainline until now. Well, maybe drm_bridge has been merged, but so has been drm_panel. Moreover, merged code is not carved in stone, if there is a better option that could replace it, users of it can be converted to the new approach and the old one can be removed. As I believe Andrzej has demonstrated, drm_panel framework is clearly superior over drm_bridge and I can't think of any good reason why it couldn't become more generic and replace drm_bridge. Of course it can be renamed then to something more generic appropriately. Using same drm_panel framework for LDVS bridge and real panel drivers isn't reasonable to me as now because drm_panel framework would be for real panel device even if the use of drm_panel framework looks like suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver using drm_bride stuff, is good enough, and that would be why drm_bridge exists and why drm_encoder has drm_bridge. And I'm finding more generic way, how to handle LVDS bridge using super node so that LVDS bridge driver isn't embedded to connector drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be done at top level of Exynos drm. Once the binding is done, encoder of display bus driver will have drm_bridge object of LVDS bridge driver so that display bus driver can handle LVDS bridge driver. Could you explain what you mean by dt binding of LVDS bridge can be done at top level of Exynos drm ? How it will look like if there will be more bridges, one for DSI, one for HDMI, etc... What if there will be two bridges in one chain. How it will cope with video pipeline bindings? it was just my idea so I have no implementation about it yet. My idea is that crtc and encoder are binded at top level of Exynos drm as is. And for bridge support, the only difference is, in case that encoder driver has bridge, the dt binding of the encoder driver is done once last one between encoder and bridge driver is binded. It would mean that bridge driver can use driver model and it doesn't need to concern about probe order issue. For this, encoder driver with bridge, MIPI-DSI or eDP, would need to use component interfaces specific to Exynos drm. As a result, once the dt bindings of crtc and encoder are completed at top level, encoder driver has its own drm_bridge for bridge, and dt binding you proposed could be used without any change, and drm_panel could also be used only for real lcd panel driver. And below is a block diagram I think, DRM KMS / | \ / | \ crtc encoder connector | / \
Re: [PATCH v5 1/5] clk/samsung: add support for multiple clock providers
Hi Rahul, On 12.03.2014 15:56, Rahul Sharma wrote: Samsung CCF helper functions do not provide support to register multiple Clock Providers for a given SoC. Due to this limitation, SoC platforms are not able to use these helpers for registering multiple clock providers and are forced to bypass this layer. This layer is modified accordingly to enable the support for multiple clock providers. Clock file for exynos4, exynos5250, exynos5420, exynos5440, S3c64xx, S3c2412 and S3c2443 are also modified as per changed helper functions. Signed-off-by: Rahul Sharma rahul.sha...@samsung.com --- drivers/clk/samsung/clk-exynos4.c| 47 +++--- drivers/clk/samsung/clk-exynos5250.c | 25 +--- drivers/clk/samsung/clk-exynos5420.c | 24 --- drivers/clk/samsung/clk-exynos5440.c | 18 +++--- drivers/clk/samsung/clk-pll.c| 14 +++-- drivers/clk/samsung/clk-s3c2412.c| 29 + drivers/clk/samsung/clk-s3c2443.c| 46 +++--- drivers/clk/samsung/clk-s3c64xx.c| 44 +++-- drivers/clk/samsung/clk.c| 114 ++ drivers/clk/samsung/clk.h| 72 ++--- 10 files changed, 251 insertions(+), 182 deletions(-) Applied, thanks. Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/5] clk/samsung: add support for pll2550xx
Hi Rahul, On 12.03.2014 15:56, Rahul Sharma wrote: From: Pankaj Dubey pankaj.du...@samsung.com exynos5260 use pll2550xx and it has different bit fields for P,M,S values as compared to pll2550. Support for pll2550xx is added here. Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com Signed-off-by: Rahul Sharma rahul.sha...@samsung.com Signed-off-by: Arun Kumar K arun...@samsung.com --- drivers/clk/samsung/clk-pll.c | 108 + drivers/clk/samsung/clk-pll.h |1 + 2 files changed, 109 insertions(+) Applied, thanks. Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 3/5] clk/samsung: add support for pll2650xx
Hi Rahul, On 12.03.2014 15:56, Rahul Sharma wrote: Add support for pll2650xx in samsung pll file. This PLL variant is close to pll36xx but uses CON2 registers instead of CON1. Aud_pll in Exynos5260 is pll2650xx and uses this code. Signed-off-by: Rahul Sharma rahul.sha...@samsung.com --- drivers/clk/samsung/clk-pll.c | 101 + drivers/clk/samsung/clk-pll.h |1 + 2 files changed, 102 insertions(+) Applied with Pankaj's reviewed-by, thanks. Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/1] clk: exynos-5420: Fix VPLL lock offset
On 13 March 2014 17:23, Tomasz Figa t.f...@samsung.com wrote: Hi Sachin, On 13.03.2014 04:27, Sachin Kamat wrote: Set it as per the user manual. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- Looks fine. Will queue for 3.15, since ATM there is no support for PLL rate setting on Exynos 5420 (no rate tables registered). Yes, that is correct. Thanks Tomasz. -- With warm regards, Sachin -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/3] ARM: dts: add dts files for exynos5260 SoC
Hi, On 12.03.2014 16:16, Rahul Sharma wrote: The patch adds the dts files for exynos5260. Signed-off-by: Pankaj Dubey pankaj.du...@samsung.com Signed-off-by: Rahul Sharma rahul.sha...@samsung.com Signed-off-by: Arun Kumar K arun...@samsung.com Reviewed-by: Tomasz Figa t.f...@samsung.com --- arch/arm/boot/dts/exynos5260-pinctrl.dtsi | 574 + arch/arm/boot/dts/exynos5260.dtsi | 400 2 files changed, 974 insertions(+) create mode 100644 arch/arm/boot/dts/exynos5260-pinctrl.dtsi create mode 100644 arch/arm/boot/dts/exynos5260.dtsi [snip] + mmc_0: mmc0@1214 { Node names should specify type of the device, so unit-specific IDs should be avoided. Please simply use mmc@1214. The same comment for remaining MMC nodes below. Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 00/21] Add DSI display support for Exynos based boards
2014-03-13 22:41 GMT+09:00 Andrzej Hajda a.ha...@samsung.com: On 03/13/2014 08:08 AM, Inki Dae wrote: 2014-03-12 20:16 GMT+09:00 Tomasz Figa t.f...@samsung.com: On 12.03.2014 11:08, Inki Dae wrote: 2014-03-07 19:00 GMT+09:00 Andrzej Hajda a.ha...@samsung.com: On 03/05/2014 03:56 AM, Inki Dae wrote: Hi Andrzej, Thanks for your contributions. 2014-02-12 20:31 GMT+09:00 Andrzej Hajda a.ha...@samsung.com: Hi, This patchset adds drivers and bindings to the following devices: - Exynos DSI master, - S6E8AA0 DSI panel, - TC358764 DSI/LVDS bridge, - HV070WSA-100 LVDS panel. It adds also display support in DTS files for the following boards: - Exynos4210/Trats, - Exynos4412/Trats2, - Exynos5250/Arndale. Things worth mentioning: 1. I have implemented DSI/LVDS bridge using drm_panel framework, ie. the driver exposes drm_panel interface on DSI side, and interact with panels on LVDS side using drm_panel framework. This approach seems to me simpler and more natural than using drm_bridge. Can you give me more details about why you think better to use panel framework than using drm_bridge? Simpler and more natural are ambiguous to me. In this particular case DSI master expects on the other end any device having DSI slave interface, it could be panel or bridge. So it seems natural that both types of slave devices should expose the same interface also on programming level. Another problem with drm_bridge is that it is not scalable - if some manufacturer will decide to add another block between the bridge and the panel there is no drm component which can be used for it. Using drm_panel the way I have used in toshiba bridge makes scalability possible, it will be only a matter of adding a driver for new block and making proper links in device tree, I see no easy way of doing it with drm_bridge approach. Now drm_bridge may not cover all hardware. However drm_bridge has already been merged to mainline so I think we need to use drm_bridge somehow instead of using other one, and also we could extend drm_bridge if needed. It would be definitely impossible for a new framework to cover all hardware because there may be other hardware not appeared yet. That is what we are doing for mainline until now. Well, maybe drm_bridge has been merged, but so has been drm_panel. Moreover, merged code is not carved in stone, if there is a better option that could replace it, users of it can be converted to the new approach and the old one can be removed. As I believe Andrzej has demonstrated, drm_panel framework is clearly superior over drm_bridge and I can't think of any good reason why it couldn't become more generic and replace drm_bridge. Of course it can be renamed then to something more generic appropriately. Using same drm_panel framework for LDVS bridge and real panel drivers isn't reasonable to me as now because drm_panel framework would be for real panel device even if the use of drm_panel framework looks like suitable to LVDS bridge driver. I thought Sean's way, ptn3460 driver using drm_bride stuff, is good enough, and that would be why drm_bridge exists and why drm_encoder has drm_bridge. And I'm finding more generic way, how to handle LVDS bridge using super node so that LVDS bridge driver isn't embedded to connector drivers such as eDP and MIPI-DSI, and dt binding of LVDS bridge can be done at top level of Exynos drm. Once the binding is done, encoder of display bus driver will have drm_bridge object of LVDS bridge driver so that display bus driver can handle LVDS bridge driver. Could you explain what you mean by dt binding of LVDS bridge can be done at top level of Exynos drm ? How it will look like if there will be more bridges, one for DSI, one for HDMI, etc... What if there will be two bridges in one chain. How it will cope with video pipeline bindings? it was just my idea so I have no implementation about it yet. My idea is that crtc and encoder are binded at top level of Exynos drm as is. And for bridge support, the only difference is, in case that encoder driver has bridge, the dt binding of the encoder driver is done once last one between encoder and bridge driver is binded. It would mean that bridge driver can use driver model and it doesn't need to concern about probe order issue. For this, encoder driver with bridge, MIPI-DSI or eDP, would need to use component interfaces specific to Exynos drm. As a result, once the dt bindings of crtc and encoder are completed at top level, encoder driver has its own drm_bridge for bridge, and dt binding you proposed could be used without any change, and drm_panel could also be used only for real lcd panel driver. And below is a block diagram I think, DRM KMS / | \ / | \ crtc encoder
Re: [PATCHv2 0/8] devfreq: exynos4: Support dt and use common ppmu driver
Hi, On Thursday, March 13, 2014 05:17:21 PM Chanwoo Choi wrote: This patchset support devicetree and use common ppmu driver instead of individual code of exynos4_bus.c to remove duplicate code. Also this patchset get the resources for busfreq from dt data by using DT helper function. - PPMU register address - PPMU clock - Regulator for INT/MIF block This patchset use SET_SYSTEM_SLEEP_PM_OPS macro intead of legacy method. To remove power-leakage in suspend state, before entering suspend state, disable ppmu clocks. Changes from v1: - Add exynos4_bus.txt documentation for devicetree guide - Fix probe failure if CONFIG_PM_OPP is disabled - Fix typo and resource leak(regulator/clock/memory) when happening probe failure - Add additionally comment for PPMU usage instead of previous PPC - Split separate patch to remove ambiguous of patch Chanwoo Choi (8): devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data devfreq: exynos4: Add ppmu's clock control and code clean about regulator control devfreq: exynos4: Fix bug of resource leak and code clean on probe() devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro devfreq: exynos4: Fix power-leakage of clock on suspend state devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail devfreq: exynos4: Add busfreq driver for exynos4210/exynos4x12 .../devicetree/bindings/devfreq/exynos4_bus.txt| 49 +++ drivers/devfreq/Kconfig| 1 + drivers/devfreq/exynos/Makefile| 2 +- drivers/devfreq/exynos/exynos4_bus.c | 415 ++--- 4 files changed, 341 insertions(+), 126 deletions(-) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt Thanks for updating this patchset. There are still some minor issues left though: - patch #4 should be at beginning of the patch series - moving of devfreq_unregister_opp_notifier(dev, data-devfreq) from exynos4_bus_exit() to exynos4_busfreq_remove() should be in patch #4 (which should really be at the beggining of patch series) not #3 - handling of iounmap(data-ppmu[i].hw_base) should be added to exynos4_bus_exit() in patch #2 not #3 - patch #8 summary and description should mention fact that it adds DT binding documentation (not the driver itself) and the patch itself can be slighlty polished One important note about this patchset not mentioned in the cover letter is that it is improving currently unused driver (because of DT-only mach-exynos conversion the only user was removed in June 2013 and from the reading the code I suspect that even that user hadn't worked previously). As such this patch series should not cause any regressions. Best regards, -- Bartlomiej Zolnierkiewicz Samsung RD Institute Poland Samsung Electronics -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2 8/8] devfreq: exynos4: Add busfreq driver for exynos4210/exynos4x12
On Thursday, March 13, 2014 05:17:29 PM Chanwoo Choi wrote: This patch add busfreq driver for Exynos4210/Exynos4x12 memory interface This patch adds DT binding documentation not the driver itself. Same comment for the patch summary line. and bus to support DVFS(Dynamic Voltage Frequency Scaling) according to PPMU counters. PPMU (Performance Profiling Monitorings Units) of Exynos4 SoC provides PPMU counters for DMC(Dynamic Memory Controller) to check memory bus utilization and then busfreq driver adjusts dynamically the operating frequency/voltage by using DEVFREQ Subsystem. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- .../devicetree/bindings/devfreq/exynos4_bus.txt| 49 ++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt diff --git a/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt new file mode 100644 index 000..2a83fcc --- /dev/null +++ b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt @@ -0,0 +1,49 @@ + +Exynos4210/4x12 busfreq driver +- + +Exynos4210/4x12 Soc busfreq driver with devfreq for Memory bus frequency/voltage SoC +scaling according to PPMU counters of memory controllers + +Required properties: +- compatible : should contain Exynos4 SoC type as follwoing: following + - samsung,exynos4x12-busfreq for Exynos4x12 + - samsung,exynos4210-busfreq for Exynos4210 +- reg: offset and length of the ppmudmc0/1 + - PPMU (Performance Profiling Monitoring Units) + : It is to profile performance event of DMC(Dynamic Memory + Controller) So, exynos4_bus.c can check memory bus utilization + by using PPMU of Exynos4 SoC. It can be improved by changing ordering, i.e. : PPMU of Exynos4 SoC is used to profile performance event of DMC (Dynamic Memory Controller) so the driver can check memory bus utilization. +- clocks : clock number of ppmudmc0/1 +- clock-names: clock name of ppmudmc0/1 +- vdd_int-supply: regulator for interface block of Exynos4 + +Optional properties: +- vdd_mif-supply: regulator for DMC block of Exynos4x12 if Exynos4x12 Soc if using Exynos4x12 SoC +- regs-name : register name of ppmudmc0/1 + +All the required listed above must be defined under code busfreq with devfreq required properties +Exmaple: Example: +For Exynos4210 busfreq, please add a newline here + busfreq@106A { + compatible = samsung,exynos4210-busfreq; + reg = 0x106A 0x2000, 0x106B 0x2000; + regs-name = PPMU_DMC0, PPMU_DMC1; + clocks = clock CLK_PPMUDMC0, clock CLK_PPMUDMC1; + clock-names = ppmudmc0, ppmudmc1; + + vdd_int-supply = buck3_reg; + }; + +For Exynos4x12 busfreq, ditto + busfreq@106A { + compatible = samsung,exynos4x12-busfreq; + reg = 0x106A 0x2000, 0x106B 0x2000; + regs-name = PPMU_DMC0, PPMU_DMC1; + clocks = clock CLK_PPMUDMC0, clock CLK_PPMUDMC1; + clock-names = ppmudmc0, ppmudmc1; + + vdd_mif-suppy = buck1_reg; + vdd_int-supply = buck3_reg; + }; Best regards, -- Bartlomiej Zolnierkiewicz Samsung RD Institute Poland Samsung Electronics -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] ARM: DT: fix gic interrupt controller documentation
When using interrupt-maps, the size of a map entry is #address-cells + #interrupt-cells for the parent interrupt controller. For the ARM GIC address-cells should be 0 as this is not used. This patch fixes the example by correctly specifying #address-cells = 0. Signed-off-by: Tim Harvey thar...@gateworks.com Cc: Jason Gunthorpe jguntho...@obsidianresearch.com Cc: Jingoo Han jg1@samsung.com Cc: Lucas Stach l.st...@pengutronix.de Cc: Mark Rutland mark.rutl...@arm.com Cc: linux-samsung-soc linux-samsung-soc@vger.kernel.org Cc: Richard Zhu r65...@freescale.com Cc: Sascha Hauer ker...@pengutronix.de Cc: Arnd Bergmann a...@arndb.de Cc: Stephen Warren swar...@wwwdotorg.org Cc: Bjorn Helgaas bhelg...@google.com Cc: Simon Horman ho...@verge.net.au Cc: Thierry Reding thierry.red...@gmail.com Cc: Ben Dooks ben-li...@fluff.org Cc: linux-tegra linux-te...@vger.kernel.org Cc: Kukjin Kim kgene@samsung.com Cc: Shawn Guo shawn@linaro.org Cc: Grant Likely grant.lik...@linaro.org --- Documentation/devicetree/bindings/arm/gic.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt index bae0d87..b59ff1f 100644 --- a/Documentation/devicetree/bindings/arm/gic.txt +++ b/Documentation/devicetree/bindings/arm/gic.txt @@ -55,7 +55,7 @@ Example: intc: interrupt-controller@fff11000 { compatible = arm,cortex-a9-gic; #interrupt-cells = 3; - #address-cells = 1; + #address-cells = 0; interrupt-controller; reg = 0xfff11000 0x1000, 0xfff10100 0x100; -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] ARM: dts: imx: fix invalid #address-cells value
The invalid value of #address-cells in the imx6 pcie host controller node causes of_irq_parse_raw() to incorrectly advance through an interrupt-map table of more than one interrupt. This patch resolves this issue and allows proper interrupt mapping for an imx6 pcie host connected to a P2P bridge when using legacy interrupts. Signed-off-by: Tim Harvey thar...@gateworks.com Cc: Jason Gunthorpe jguntho...@obsidianresearch.com Cc: Jingoo Han jg1@samsung.com Cc: Lucas Stach l.st...@pengutronix.de Cc: Mark Rutland mark.rutl...@arm.com Cc: linux-samsung-soc linux-samsung-soc@vger.kernel.org Cc: Richard Zhu r65...@freescale.com Cc: Sascha Hauer ker...@pengutronix.de Cc: Arnd Bergmann a...@arndb.de Cc: Stephen Warren swar...@wwwdotorg.org Cc: Bjorn Helgaas bhelg...@google.com Cc: Simon Horman ho...@verge.net.au Cc: Thierry Reding thierry.red...@gmail.com Cc: Ben Dooks ben-li...@fluff.org Cc: linux-tegra linux-te...@vger.kernel.org Cc: Kukjin Kim kgene@samsung.com Cc: Shawn Guo shawn@linaro.org Cc: Grant Likely grant.lik...@linaro.org --- arch/arm/boot/dts/imx6qdl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index af8d28d..2285299 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -49,7 +49,7 @@ intc: interrupt-controller@00a01000 { compatible = arm,cortex-a9-gic; #interrupt-cells = 3; - #address-cells = 1; + #address-cells = 0; #size-cells = 1; interrupt-controller; reg = 0x00a01000 0x1000, -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/6] PCI: designware: use new OF interrupt mapping when possible
On Thu, Mar 6, 2014 at 7:33 AM, Marek Vasut ma...@denx.de wrote: On Thursday, March 06, 2014 at 03:47:03 AM, Jingoo Han wrote: On Wednesday, March 05, 2014 10:26 PM, Lucas Stach wrote: This is the recommended method of doing the IRQ mapping. For old devicetrees we fall back to the previous practice. Signed-off-by: Lucas Stach l.st...@pengutronix.de Acked-by: Arnd Bergmann a...@arndb.de (+cc Mohit KUMAR, Richard Zhu, Pratyush Anand, Marek Vasut, Kishon Vijay Abraham I) Acked-by: Jingoo Han jg1@samsung.com It works properly on Exynos platform. Thank you. Looks reasonable, Reviewed-by: Marek Vasut ma...@denx.de I've tested this on the Gateworks Ventana products with P2P bridges and with the patch I just submitted here: http://thread.gmane.org/gmane.linux.kernel.pci/30017 Tested-by: Tim Harvey thar...@gateworks.com Tim -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ARM: DT: fix gic interrupt controller documentation
On 03/13/2014 11:40 AM, Tim Harvey wrote: When using interrupt-maps, the size of a map entry is #address-cells + #interrupt-cells for the parent interrupt controller. For the ARM GIC address-cells should be 0 as this is not used. This patch fixes the example by correctly specifying #address-cells = 0. If the #address-cells property is required (well, or even optional...) in the node, shouldn't it be included in the list of required/optional properties above, and not solely included in the example? -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2 8/8] devfreq: exynos4: Add busfreq driver for exynos4210/exynos4x12
On Thu, Mar 13, 2014 at 08:17:29AM +, Chanwoo Choi wrote: This patch add busfreq driver for Exynos4210/Exynos4x12 memory interface and bus to support DVFS(Dynamic Voltage Frequency Scaling) according to PPMU counters. PPMU (Performance Profiling Monitorings Units) of Exynos4 SoC provides PPMU counters for DMC(Dynamic Memory Controller) to check memory bus utilization and then busfreq driver adjusts dynamically the operating frequency/voltage by using DEVFREQ Subsystem. Signed-off-by: Chanwoo Choi cw00.c...@samsung.com --- .../devicetree/bindings/devfreq/exynos4_bus.txt| 49 ++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt diff --git a/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt new file mode 100644 index 000..2a83fcc --- /dev/null +++ b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt @@ -0,0 +1,49 @@ + +Exynos4210/4x12 busfreq driver +- + +Exynos4210/4x12 Soc busfreq driver with devfreq for Memory bus frequency/voltage +scaling according to PPMU counters of memory controllers + +Required properties: +- compatible : should contain Exynos4 SoC type as follwoing: + - samsung,exynos4x12-busfreq for Exynos4x12 + - samsung,exynos4210-busfreq for Exynos4210 Is there a device called busfreq? What device does this binding describe? +- reg: offset and length of the ppmudmc0/1 + - PPMU (Performance Profiling Monitoring Units) You seem to require a particular order here. It would be good to be explicit about it. + : It is to profile performance event of DMC(Dynamic Memory + Controller) So, exynos4_bus.c can check memory bus utilization + by using PPMU of Exynos4 SoC. This is superfluous, and Linux-specific. The binding document shouldn't need to refer to drivers. +- clocks : clock number of ppmudmc0/1 +- clock-names: clock name of ppmudmc0/1 Are these two clocks, or one clock with a slash in the name? Please list each name separately. +- vdd_int-supply: regulator for interface block of Exynos4 + +Optional properties: +- vdd_mif-supply: regulator for DMC block of Exynos4x12 if Exynos4x12 Soc +- regs-name : register name of ppmudmc0/1 This is completely nonstandard. Did you mean reg-names? Please be explicit about the names you expect. Write them in full, quoted, and describe the relationship to the reg property. + +All the required listed above must be defined under code busfreq with devfreq I'm having some difficulty figuring out what exactly this is intended to mean. Thanks, Mark. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ARM: DT: fix gic interrupt controller documentation
On Thu, Mar 13, 2014 at 11:44:33AM -0600, Stephen Warren wrote: On 03/13/2014 11:40 AM, Tim Harvey wrote: When using interrupt-maps, the size of a map entry is #address-cells + #interrupt-cells for the parent interrupt controller. For the ARM GIC address-cells should be 0 as this is not used. This patch fixes the example by correctly specifying #address-cells = 0. If the #address-cells property is required (well, or even optional...) in the node, shouldn't it be included in the list of required/optional properties above, and not solely included in the example? AFAIK, #address-cells = 0 is the same as not including a #address-cells at all. Omitting entirely is what other interrupt-controller bindings are doing, so I'd just drop mention of #address-cells completely. Jason -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/3] ARM: dts: add dts files for exynos5260 SoC
On 13.03.2014 06:06, Rahul Sharma wrote: On 13 March 2014 06:28, Pankaj Dubey pankaj.du...@samsung.com wrote: On 03/13/2014 12:16 AM, Rahul Sharma wrote: [snip] + clocks { + compatible = simple-bus; + #address-cells = 1; + #size-cells = 0; Even though you added #address-cells property I can not see reg property in any of fixed-clock. Isn't it better either we can remove this or add reg property? Also all these fixed-clock are missing #clock-cells property. Since it is a soc level addition, I enabled provision for adding reg property for fixed clocks in boards files (or in SoC file). All sub-nodes should follow the same pattern. After recent discussion with DT people, the conclusion is that simple-bus should be used only for MMIO platform devices with reg values mapped directly into address space in which the simple-bus node resides. So for now I'd remove the grouping and keep the clocks in soc node directly. [snip] + + dptx_phy_ch0: phyclk_dptx_phy_ch0_txd { + compatible = fixed-clock; + clock-frequency = 27000; + clock-output-names = phyclk_dptx_phy_ch0_txd_clk; + }; I'm not sure whether these clocks are really fixed clocks. They are output from certain PHY blocks which are not always-on, while using the fixed clock binding would suggest otherwise. IMHO they should be hidden inside the clock driver, without DT IDs assigned as a temporary hack, until proper support gets added for them (e.g. proper clock provider from appropriate PHY). Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 3/3] ARM: dts: add dts files for xyref5260 board
On 13.03.2014 06:01, Rahul Sharma wrote: Thanks Pankaj, On 13 March 2014 06:19, Pankaj Dubey pankaj.du...@samsung.com wrote: Hi Rahul, On 03/13/2014 12:16 AM, Rahul Sharma wrote: The patch adds the dts files for xyref5260 board which is based on Exynos5260 Evt0 sample. Signed-off-by: Rahul Sharma rahul.sha...@samsung.com --- arch/arm/boot/dts/Makefile |1 + arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts | 110 +++ 2 files changed, 111 insertions(+) create mode 100644 arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b9d6a8b..5a391bf 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ exynos5250-arndale.dtb \ exynos5250-smdk5250.dtb \ exynos5250-snow.dtb \ + exynos5260-xyref5260-evt0.dtb \ exynos5420-arndale-octa.dtb \ exynos5420-smdk5420.dtb \ exynos5440-sd5v1.dtb \ diff --git a/arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts b/arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts new file mode 100644 index 000..d7d0aeb --- /dev/null +++ b/arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts @@ -0,0 +1,110 @@ +/* + * SAMSUNG XYREF5260 EVT0 board device tree source + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +#include exynos5260.dtsi + +/ { + model = SAMSUNG XYREF5260 EVT0 board based on EXYNOS5260; + compatible = samsung,xyref5260, samsung,exynos5260; + + memory { + reg = 0x2000 0x8000; + }; + + chosen { + bootargs = console=ttySAC2,115200; + }; + + clocks { + fin_pll: xxti { + compatible = fixed-clock; + clock-frequency = 2400; + clock-output-names = fin_pll; + #clock-cells = 0; + }; + + xrtcxti: xrtcxti { + compatible = fixed-clock; + clock-frequency = 32768; + clock-output-names = xrtcxti; + }; clock-cells property is missing here. I have added #clock-cells only for clocks which are supposed to be referred. IMO we need it otherwise. The fixed-clock binding requires the #clock-cells property to be present with value of 0. It is not a valid fixed-clock otherwise. + + spdif_extclk: ioclk_spdif_extclk { + compatible = fixed-clock; + clock-frequency = 49152000; + clock-output-names = ioclk_spdif_extclk; + }; ditto. + }; +}; May I know why other phyclocks and ioclks have not been added? Phyclocks should be added in SoC file. Please refer the other patch. Ioclocks have 2 dimensions. 1) A board may or may not have these. But if board doesn't have them, we may end up with orphans in clock tree. 2) Adding them in SoC is not meaningful because rate is board dependent and cannot be mentioned in SoC file. Without rate, probe will not be successful. What I followed here is adding IO clocks which are resulting into orphan clocks. Only clocks with active parents set to missing ioclocks will be orphaned. If a mux has an ioclock as its default parent, it can be still reconfigured to another input normally. What we can do is to allow the registration of fixed-io-clocks in clock driver which are provided without RATE? If this looks good, I can post the respective patch for clock driver and dt correction. I believe ioclocks should be registered properly using DT, only if present. It is important, because such ioclock might not be an always-on fixed rate clock, but instead a configurable external clock generator. Best regards, Tomasz -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 RE-SEND 0/7] add new Samsung SXGbE driver
From: Byungho An bh74...@samsung.com Date: Thu, 13 Mar 2014 15:55:28 +0900 This is 2nd posting for Samsung SXGbE driver and just re-sending because of line wrapping in previous posting. Changes since v1: - changed name of driver to SXGbE as per Ben's comment - squashed Joe's neatening for many stuff in original patches I'm mostly happy with this driver, but all of those module parameters have to be removed except for 'debug'. They duplicate functionality provided by ethtool. Module parameters are strongly, if not completely, discouraged. A suitable generic configuration mechanism, such as ethtool, should always be used instead. -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ARM: DT: fix gic interrupt controller documentation
On Thu, Mar 13, 2014 at 11:25 AM, Jason Gunthorpe jguntho...@obsidianresearch.com wrote: On Thu, Mar 13, 2014 at 11:44:33AM -0600, Stephen Warren wrote: On 03/13/2014 11:40 AM, Tim Harvey wrote: When using interrupt-maps, the size of a map entry is #address-cells + #interrupt-cells for the parent interrupt controller. For the ARM GIC address-cells should be 0 as this is not used. This patch fixes the example by correctly specifying #address-cells = 0. If the #address-cells property is required (well, or even optional...) in the node, shouldn't it be included in the list of required/optional properties above, and not solely included in the example? AFAIK, #address-cells = 0 is the same as not including a #address-cells at all. Omitting entirely is what other interrupt-controller bindings are doing, so I'd just drop mention of #address-cells completely. Jason Jason / Stephen, Yes, it does indeed default to 0 if not specified. For arm-gic it would appear #address-cells must be 0, so should we remove all places its set explicitly to 0 in dts as wel as the example in Documentation/devicetree/bindings? Looking through arch/arm/boot/dts I'm seeing other dts configs using 'arm,cortex-a9-gic' which I'm guessing are equally as wrong as the imx6 situation: - arch/arm/boot/dts/highbank.dts - arch/arm/boot/dts/sh73a0.dtsi I'm also seeing a number of places where its set explicitly to 0: - Documentation/devicetree/bindings/arm/gic.txt - Documentation/devicetree/bindings/arm/vexpress.txt - arch/arm/boot/dts/bcm11351.dtsi - arch/arm/boot/dts/hi3620.dtsi - arch/arm/boot/dts/imx6qdl.dtsi - arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts If I extend this search to the other compatible gic interrupt controllers implemented in drivers/irqchip/irq-gic.c (arm,cortex-a15-gic, qcom,msm-8660-qgic, qcom,msm-qgic2) I find even more examples where #address-cells is set explicitly to 0 or to 1 (and I would believe a value of 1 is invalid, just as it is in my case). I'm happy to broaden my patch, but I certainly want to make sure I'm doing the right thing with it, as I don't have the ability to test all the other devicetree configs and am by no means a devicetree expert. Recommendations? Tim -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 RE-SEND 1/7] net: sxgbe: add basic framework for Samsung 10Gb ethernet driver
Byungho An bh74...@samsung.com : From: Siva Reddy siva.kal...@samsung.com This patch adds support for Samsung 10Gb ethernet driver(sxgbe). - sxgbe core initialization - Tx and Rx support - MDIO support - ISRs for Tx and Rx - ifconfig support to driver You'll find a partial review below. [...] diff --git a/drivers/net/ethernet/samsung/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe_common.h new file mode 100644 index 000..3f16220 --- /dev/null +++ b/drivers/net/ethernet/samsung/sxgbe_common.h [...] +enum dma_irq_status { + tx_hard_error = BIT(0), + tx_bump_tc = BIT(1), + handle_tx = BIT(2), + rx_hard_error = BIT(3), + rx_bump_tc = BIT(4), + handle_rx = BIT(5), Please use tabs before = to line things up. [...] +struct sxgbe_hwtimestamp { + void (*config_hw_tstamping)(void __iomem *ioaddr, u32 data); + void (*config_sub_second_increment)(void __iomem *ioaddr); + int (*init_systime)(void __iomem *ioaddr, u32 sec, u32 nsec); + int (*config_addend)(void __iomem *ioaddr, u32 addend); + int (*adjust_systime)(void __iomem *ioaddr, u32 sec, u32 nsec, + int add_sub); + u64 (*get_systime)(void __iomem *ioaddr); +}; None of these method is ever used. Even annotated with __iomem, I'd rather keep the void * to a minimum and push the device driver pointer through the call chain. Your call. [...] +struct sxgbe_core_ops { + /* MAC core initialization */ + void (*core_init)(void __iomem *ioaddr); + /* Dump MAC registers */ + void (*dump_regs)(void __iomem *ioaddr); + /* Handle extra events on specific interrupts hw dependent */ + int (*host_irq_status)(void __iomem *ioaddr, +struct sxgbe_extra_stats *x); + /* Set power management mode (e.g. magic frame) */ + void (*pmt)(void __iomem *ioaddr, unsigned long mode); + /* Set/Get Unicast MAC addresses */ + void (*set_umac_addr)(void __iomem *ioaddr, unsigned char *addr, + unsigned int reg_n); + void (*get_umac_addr)(void __iomem *ioaddr, unsigned char *addr, + unsigned int reg_n); + void (*enable_rx)(void __iomem *ioaddr, bool enable); + void (*enable_tx)(void __iomem *ioaddr, bool enable); + + /* controller version specific operations */ + int (*get_controller_version)(void __iomem *ioaddr); + + /* If supported then get the optional core features */ + unsigned int (*get_hw_feature)(void __iomem *ioaddr, +unsigned char feature_index); + /* adjust SXGBE speed */ + void (*set_speed)(void __iomem *ioaddr, unsigned char speed); +}; This indirection level is never used. + +const struct sxgbe_core_ops *sxgbe_get_core_ops(void); + +struct sxgbe_ops { + const struct sxgbe_core_ops *mac; + const struct sxgbe_desc_ops *desc; + const struct sxgbe_dma_ops *dma; + const struct sxgbe_mtl_ops *mtl; Will these indirection levels ever be used ? + const struct sxgbe_hwtimestamp *ptp; + struct mii_regs mii;/* MII register Addresses */ + struct mac_link link; + unsigned int ctrl_uid; + unsigned int ctrl_id; +}; + +/* SXGBE private data structures */ +struct sxgbe_tx_queue { + u8 queue_no; + unsigned int irq_no; + struct sxgbe_priv_data *priv_ptr; + struct sxgbe_tx_norm_desc *dma_tx; You may lay things a bit differently. [...] +/* SXGBE HW capabilities */ +struct sxgbe_hw_features { + /** CAP [0] ***/ + unsigned int gmii_1000mbps; This field is never read. + unsigned int vlan_hfilter; This field is never read. + unsigned int sma_mdio; This field is never read. + unsigned int pmt_remote_wake_up; This field *is* read. + unsigned int pmt_magic_frame; So is this one. + unsigned int rmon; But this one isn't :o/ + unsigned int arp_offload; Sic. The storage is a bit expensive. You may pack some boolean into a single unsigned int. [...] +struct sxgbe_priv_data { + /* DMA descriptos */ + struct sxgbe_tx_queue *txq[SXGBE_TX_QUEUES]; + struct sxgbe_rx_queue *rxq[SXGBE_RX_QUEUES]; + u8 cur_rx_qnum; + + unsigned int dma_tx_size; + unsigned int dma_rx_size; + unsigned int dma_buf_sz; + u32 rx_riwt; + + struct napi_struct napi; + + void __iomem *ioaddr; + struct net_device *dev; + struct device *device; + struct sxgbe_ops *hw;/* sxgbe specific ops */ + int no_csum_insertion; + spinlock_t lock; There is no spin_lock_init for this field. OTOH it isn't really used at all. [...] + int oldlink; + int speed; + int oldduplex; + unsigned int flow_ctrl; + unsigned int pause; You may add some extra inner struct when fields are related. [...] diff --git a/drivers/net/ethernet/samsung/sxgbe_desc.c
RE: [PATCH v2 1/3] arm64: dts: add initial dts for Samsung GH7 SoC and SSDK-GH7 board
Mark Rutland wrote: [...] +/memreserve/ 0x8000 0x0C40; Please have a comment as to what this memreserve is intended to protect. This is very large, and we don't want pointless memreserves. Well, you mean I need to comment about each reserved memory area? Please have a comment about what each /memreserve/ is intended to protect. OK and I will try to reduce the size of reserved memory. We need the reserved memory for EL3 monitor, UEFI services, secure interpreter, hypervisor and Scan-chain for debug...BTW isn't it depending on each hardware platform and usage model? If it depends on each particular model then it doesn't belong in the shared dtsi, and each dts should have the /memreserve/ for that platform. I mean it depends on each SoC not board :-) Why would the hypervisor or secure OS memory ever be accessible to the kernel such that it would require a memreserve? That sounds fundamentally broken. I was under the impression that if using UEFI we can identify and reserve the UEFI services by walking to UEFI memory map. If we don't use them, they don't need to be protected. As such, I don't see why they need a memreserve for them. I need to talk to regarding engineer internally. Then I will update it. Just note, I will change the reserve memory area and size. From at 0xf800 and size is 128MB(0x800). Ok. What address does the kernel end up getting loaded at on this board? We load the kernel image from at 0x8008 after changing the reserve memory area. Ok. [...] + cpu@000 { + device_type = cpu; + compatible = arm,armv8; The arm,armv8 should be a fallback rather than the only entry. The precise core should be first (see arch/arm64/boot/dts/apm-storm.dtsi for an example). Well, do I really need another name if GH7 has just 'ARMv8 core' exactly? Yes please. You presumably don't have just 'ARMv8 core', but rather a specific ARMv8 implementation. OK, so in my understanding if it is really _just_ 'ARMv8 core' from S/W point of view, arm,armv8 should be fine. I will make sure. + reg = 0x0 0x000; Any reason for padding these to three hexadecimal digits (in both the reg and unit-address)? Yes, I already commented on Olof's question before, other cores will be added and it should be separated from this. Ok. [...] + gic: interrupt-controller@1C00 { + compatible = arm,cortex-a15-gic; We should have a more specific compatible string early in the list here too. Well, I think more specific compatible string is not required for gic, there were discussion about using another compatible string for gic-v2. And cortex-a15-gic should be fine at this moment and if another name is required as per previous discussion, we will then. While it's probably ok to have arm,cortex-a15-gic in the compatible list, it would be good to also have a more specific string, so we can identify the GIC implementation precisely in future (in case we need to perform any workarounds, or there's some kind of optimisation we could perform for some implementations). Hmm... let's use just it for now then add another specific string later ;-) [...] + pmu { + compatible = arm,armv8-pmuv3; This is missing a specific compatible string. I don't know why I need another specific compatible string here because I thought the 'armv8-pmuv3' is enough. Each CPU microarchitecture has different PMU events and quirks. While the CPU PMU might be compatible with ARMv8's PMUv3, it will also have implementation-specific events, and may have quirks we need to work around in future. As with 32-bit, we'd expect these to be of the form ${implementor},${cpu}-pmu. OK. + compatible = samsung,gh7-pmu, armv8-pmuv3; + interrupts = 0 294 0, +0 295 0, +0 296 0, +0 297 0, +0 298 0, +0 299 0, +0 300 0, +0 301 0; + }; There are four CPUs described, yet eight interrupts here. There should be one per CPU. Yes right. I added them here by mistake, the other four interrupts will be used for other 4 cores will be added later though. Ok. [...] + serial@12c2 { + compatible = arm,pl011, arm,primecell; + reg = 0 0x12c2 0 0x1; + interrupts = 0 420 0; + }; These are both missing required clocks. Yes right. So you'll add these? To be honest, still I'm not sure how it should be handled because regarding clocks do not need to handle in the
Re: [PATCHv2 0/8] devfreq: exynos4: Support dt and use common ppmu driver
Hi, On 03/14/2014 01:43 AM, Bartlomiej Zolnierkiewicz wrote: Hi, On Thursday, March 13, 2014 05:17:21 PM Chanwoo Choi wrote: This patchset support devicetree and use common ppmu driver instead of individual code of exynos4_bus.c to remove duplicate code. Also this patchset get the resources for busfreq from dt data by using DT helper function. - PPMU register address - PPMU clock - Regulator for INT/MIF block This patchset use SET_SYSTEM_SLEEP_PM_OPS macro intead of legacy method. To remove power-leakage in suspend state, before entering suspend state, disable ppmu clocks. Changes from v1: - Add exynos4_bus.txt documentation for devicetree guide - Fix probe failure if CONFIG_PM_OPP is disabled - Fix typo and resource leak(regulator/clock/memory) when happening probe failure - Add additionally comment for PPMU usage instead of previous PPC - Split separate patch to remove ambiguous of patch Chanwoo Choi (8): devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data devfreq: exynos4: Add ppmu's clock control and code clean about regulator control devfreq: exynos4: Fix bug of resource leak and code clean on probe() devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro devfreq: exynos4: Fix power-leakage of clock on suspend state devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail devfreq: exynos4: Add busfreq driver for exynos4210/exynos4x12 .../devicetree/bindings/devfreq/exynos4_bus.txt| 49 +++ drivers/devfreq/Kconfig| 1 + drivers/devfreq/exynos/Makefile| 2 +- drivers/devfreq/exynos/exynos4_bus.c | 415 ++--- 4 files changed, 341 insertions(+), 126 deletions(-) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt Thanks for updating this patchset. There are still some minor issues left though: - patch #4 should be at beginning of the patch series - moving of devfreq_unregister_opp_notifier(dev, data-devfreq) from exynos4_bus_exit() to exynos4_busfreq_remove() should be in patch #4 (which should really be at the beggining of patch series) not #3 - handling of iounmap(data-ppmu[i].hw_base) should be added to exynos4_bus_exit() in patch #2 not #3 - patch #8 summary and description should mention fact that it adds DT binding documentation (not the driver itself) and the patch itself can be slighlty polished OK, I'll re-order the sequence of patchset and modify minior issues about your comment. Also, I'll modify the patch description for patch8. One important note about this patchset not mentioned in the cover letter is that it is improving currently unused driver (because of DT-only mach-exynos conversion the only user was removed in June 2013 and from the reading the code I suspect that even that user hadn't worked previously). As such this patch series should not cause any regressions. I don't understand correct your meaning.I explained DT support on upper patchset description by using DT helper function and I added PPMU descritpion. Also, Each patch include detailed description of patch content. What is more needed? Best Regards, Chanwoo Choi -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 00/27] iommu/exynos: Fixes and Enhancements of System MMU driver with DT
Sorry for the delayed posting the v11 patchset. The current exynos-iommu(System MMU) driver does not work autonomously since it is lack of support for power management of peripheral blocks. For example, MFC device driver must ensure that its System MMU is disabled before MFC block is power-down not to invalidate IOTLB in the System MMU when I/O memory mapping is changed. Because a System MMU resides in the same H/W block, access to control registers of System MMU while the H/W block is turned off must be prohibited. This set of changes solves the above problem with setting each System MMUs as the parent of the device which owns the System MMU to receive the information when the device is turned off or turned on. Another big change to the driver is the support for devicetree. The bindings for System MMU is described in Documentation/devicetree/bindings/arm/samsung/system-mmu.txt In addition, this patchset also includes several bug fixes and enhancements of the current driver. Change log: v11: - Rebased on the latest works on clock, arm/samsung, iommu branches - Change the property to link System MMU and its master H/W 'iommu' in the master's node - 'mmu-masters' in the System MMU's node - Changed compatible string: samsung,sysmmu-v1 samsung,sysmmu-v2 samsung,sysmmu-v3.1 samsung,sysmmu-v3.2 samsung,sysmmu-v3.3 - Change the implementation of retrieving System MMU version - simpler - Check NULL pointer before call to clk_enable() and clk_disable() - Allow a single master to link to multiple System MMUs. (fimc-is, fimd/g2d/Scaler in Exynos5420) - Workarounds of known problems of System MMU - Code enhancements: * Compilable for 64-bit * Enhanced error messages v10: - Rebased on the following branches git.linaro.org/git-ro/people/mturquette/linux.git/clk-next git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git/for-next git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git/next git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/master (3.12-rc3) - Set parent clock to all System MMU clocks. - Add clock and DT descriptos for Exynos5420 - Modified error handling in exynos_iommu_init() - Split iommu/exynos: support for device tree patch into the following 6 patches iommu/exynos: handle only one instance of System MMU iommu/exynos: always enable runtime PM iommu/exynos: always use a single clock descriptor iommu/exynos: remove dbgname from drvdata of a System MMU iommu/exynos: use managed driver helper functions iommu/exynos: support for device tree - Remove 'interrupt-names' and 'status' properties from DT - Change n:1 relationship between master:System MMU into 1:1 relationship. - Removed custom fault handler and print the status of System MMU whenever System MMU fault is occurred. - Post Antonios Motakis's commit together: iommu/exynos: add devices attached to the System MMU to an IOMMU group v9: - Rebased on the following branches git.linaro.org/git-ro/people/mturquette/linux.git/clk-next git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git/samsung-next git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/master (3.11-rc4) - Split add bus notifier for registering System MMU into 5 patches - Call clk_prepare() that was missing in v8. - Fixed base address of sysmmu_tv in exynos4210.dtsi - BUG_ON() instead of return -EADDRINUSE when trying mapping on an mapped area - Moved camif_top to 317 in drivers/clk/samsung/clk-exynos5250.c - Removed 'iommu' property from 'codec'(mfc) node - Does not make 'master' clock to be the parent of 'sysmmu' clock. 'master' clock is enabled before accessing control registers of System MMU and disabled after the access. v8: - Reordered patch list: moved change rwloc to spinlock to the last. - Fixed remained bug in fix page table maintenance. - Always return 0 from exynos_iommu_attach_device(). - Removed prefetch buffer setting when System MMU is enabled due to the restriction of prefetch buffers: A prefetch buffer must not hit from more than one DMA. For instance with GScalers, if a single prefetch buffer is initialized with 0x0 ~ 0x and a GScaler works on source buffer at 0x1000 and target buffer @ 0x2000, the System MMU may be got deadlock. Clients must initialize prefetch buffers with custom function defined in exynos-iommu drivers whenever they need to enable prefetch buffers. - The clock of System MMU has no relationship with the clock of its master H/W. The clock of master H/W is always enabled when exynos-iommu driver needs to access MMIO area and disabled as soon as the access finishes. - Removed err_page variable used in exynos_iommu_unmap() in the previous patch fix page table maintenance. - Split a big patch add bus notifier for registering System MMU. Extracted the following 2 patches: 9/12 and 10/12. - And some additional fixes... v7: - Rebased on the stable 3.10 - Registered PM domains and gate clocks with DT - Changed connection method
[PATCH v11 01/27] iommu/exynos: do not include removed header
Commit 25e9d28d92 (ARM: EXYNOS: remove system mmu initialization from exynos tree) removed arch/arm/mach-exynos/mach/sysmmu.h header without removing remaining use of it from exynos-iommu driver, thus causing a compilation error. This patch fixes the error by removing respective include line from exynos-iommu.c. CC: Tomasz Figa t.f...@samsung.com Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 0740189..4876d35 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -12,6 +12,7 @@ #define DEBUG #endif +#include linux/kernel.h #include linux/io.h #include linux/interrupt.h #include linux/platform_device.h @@ -29,8 +30,6 @@ #include asm/cacheflush.h #include asm/pgtable.h -#include mach/sysmmu.h - /* We does not consider super section mapping (16MB) */ #define SECT_ORDER 20 #define LPAGE_ORDER 16 -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 02/27] iommu/exynos: add missing cache flush for removed page table entries
This commit adds cache flush for removed small and large page entries in exynos_iommu_unmap(). Missing cache flush of removed page table entries can cause missing page fault interrupt when a master IP accesses an unmapped area. Reviewed-by: Tomasz Figa t.f...@samsung.com Tested-by: Grant Grundler grund...@chromium.org Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 4876d35..1c3a397 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -958,6 +958,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain, if (lv2ent_small(ent)) { *ent = 0; size = SPAGE_SIZE; + pgtable_flush(ent, ent + 1); priv-lv2entcnt[lv1ent_offset(iova)] += 1; goto done; } @@ -966,6 +967,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain, BUG_ON(size LPAGE_SIZE); memset(ent, 0, sizeof(*ent) * SPAGES_PER_LPAGE); + pgtable_flush(ent, ent + SPAGES_PER_LPAGE); size = LPAGE_SIZE; priv-lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 03/27] iommu/exynos: change error handling when page table update is failed
This patch changes not to panic on any error when updating page table. Instead prints error messages with callstack. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 58 -- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 1c3a397..4a74ed8 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -812,13 +812,18 @@ finish: static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova, short *pgcounter) { + if (lv1ent_section(sent)) { + WARN(1, Trying mapping on %#08lx mapped with 1MiB page, iova); + return ERR_PTR(-EADDRINUSE); + } + if (lv1ent_fault(sent)) { unsigned long *pent; pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC); BUG_ON((unsigned long)pent (LV2TABLE_SIZE - 1)); if (!pent) - return NULL; + return ERR_PTR(-ENOMEM); *sent = mk_lv1ent_page(__pa(pent)); *pgcounter = NUM_LV2ENTRIES; @@ -829,14 +834,21 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova, return page_entry(sent, iova); } -static int lv1set_section(unsigned long *sent, phys_addr_t paddr, short *pgcnt) +static int lv1set_section(unsigned long *sent, unsigned long iova, + phys_addr_t paddr, short *pgcnt) { - if (lv1ent_section(sent)) + if (lv1ent_section(sent)) { + WARN(1, Trying mapping on 1MiB@%#08lx that is mapped, + iova); return -EADDRINUSE; + } if (lv1ent_page(sent)) { - if (*pgcnt != NUM_LV2ENTRIES) + if (*pgcnt != NUM_LV2ENTRIES) { + WARN(1, Trying mapping on 1MiB@%#08lx that is mapped, + iova); return -EADDRINUSE; + } kfree(page_entry(sent, 0)); @@ -854,8 +866,10 @@ static int lv2set_page(unsigned long *pent, phys_addr_t paddr, size_t size, short *pgcnt) { if (size == SPAGE_SIZE) { - if (!lv2ent_fault(pent)) + if (!lv2ent_fault(pent)) { + WARN(1, Trying mapping on 4KiB where mapping exists); return -EADDRINUSE; + } *pent = mk_lv2ent_spage(paddr); pgtable_flush(pent, pent + 1); @@ -864,7 +878,10 @@ static int lv2set_page(unsigned long *pent, phys_addr_t paddr, size_t size, int i; for (i = 0; i SPAGES_PER_LPAGE; i++, pent++) { if (!lv2ent_fault(pent)) { - memset(pent, 0, sizeof(*pent) * i); + WARN(1, + Trying mapping on 64KiB where mapping exists); + if (i 0) + memset(pent - i, 0, sizeof(*pent) * i); return -EADDRINUSE; } @@ -892,7 +909,7 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long iova, entry = section_entry(priv-pgtable, iova); if (size == SECT_SIZE) { - ret = lv1set_section(entry, paddr, + ret = lv1set_section(entry, iova, paddr, priv-lv2entcnt[lv1ent_offset(iova)]); } else { unsigned long *pent; @@ -900,17 +917,16 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long iova, pent = alloc_lv2entry(entry, iova, priv-lv2entcnt[lv1ent_offset(iova)]); - if (!pent) - ret = -ENOMEM; + if (IS_ERR(pent)) + ret = PTR_ERR(pent); else ret = lv2set_page(pent, paddr, size, priv-lv2entcnt[lv1ent_offset(iova)]); } - if (ret) { + if (ret) pr_debug(%s: Failed to map iova 0x%lx/0x%x bytes\n, __func__, iova, size); - } spin_unlock_irqrestore(priv-pgtablelock, flags); @@ -924,6 +940,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain, struct sysmmu_drvdata *data; unsigned long flags; unsigned long *ent; + size_t err_pgsize; BUG_ON(priv-pgtable == NULL); @@ -932,7 +949,10 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain, ent = section_entry(priv-pgtable, iova); if (lv1ent_section(ent)) { - BUG_ON(size
[PATCH v11 04/27] iommu/exynos: fix L2TLB invalidation
L2TLB is 8-way set-associative TLB with 512 entries. The number of sets is 64. A single 4KB(small page) translation information is cached only to a set whose index is the same with the lower 6 bits of the page frame number. A single 64KB(large page) translation information can be cached to any 16 sets whose top two bits of their indices are the same with the bit [5:4] of the page frame number. A single 1MB(section) or larger translation information can be cached to any set in the TLB. It is required to invalidate entire sets that may cache the target translation information to guarantee that the L2TLB has no stale data. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 31 ++- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 4a74ed8..0d26aeb 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -225,9 +225,14 @@ static void __sysmmu_tlb_invalidate(void __iomem *sfrbase) } static void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase, - unsigned long iova) + unsigned long iova, unsigned int num_inv) { - __raw_writel((iova SPAGE_MASK) | 1, sfrbase + REG_MMU_FLUSH_ENTRY); + unsigned int i; + for (i = 0; i num_inv; i++) { + __raw_writel((iova SPAGE_MASK) | 1, + sfrbase + REG_MMU_FLUSH_ENTRY); + iova += SPAGE_SIZE; + } } static void __sysmmu_set_ptbase(void __iomem *sfrbase, @@ -477,7 +482,8 @@ static bool exynos_sysmmu_disable(struct device *dev) return disabled; } -static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova) +static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, + size_t size) { unsigned long flags; struct sysmmu_drvdata *data = dev_get_drvdata(dev-archdata.iommu); @@ -487,9 +493,24 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova) if (is_sysmmu_active(data)) { int i; for (i = 0; i data-nsfrs; i++) { + unsigned int maj; + unsigned int num_inv = 1; + maj = __raw_readl(data-sfrbases[i] + REG_MMU_VERSION); + /* +* L2TLB invalidation required +* 4KB page: 1 invalidation +* 64KB page: 16 invalidation +* 1MB page: 64 invalidation +* because it is set-associative TLB +* with 8-way and 64 sets. +* 1MB page can be cached in one of all sets. +* 64KB page can be one of 16 consecutive sets. +*/ + if ((maj 28) == 2) /* major version number */ + num_inv = min_t(unsigned int, size / PAGE_SIZE, 64); if (sysmmu_block(data-sfrbases[i])) { __sysmmu_tlb_invalidate_entry( - data-sfrbases[i], iova); + data-sfrbases[i], iova, num_inv); sysmmu_unblock(data-sfrbases[i]); } } @@ -999,7 +1020,7 @@ done: spin_lock_irqsave(priv-lock, flags); list_for_each_entry(data, priv-clients, node) - sysmmu_tlb_invalidate_entry(data-dev, iova); + sysmmu_tlb_invalidate_entry(data-dev, iova, size); spin_unlock_irqrestore(priv-lock, flags); return size; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 05/27] iommu/exynos: remove prefetch buffer setting
Prefetch buffer is a cache of System MMU 3.x and caches a block of page table entries to make effect of larger page with small pages. However, how to control prefetch buffers and the specifications of prefetch buffers different from minor versions of System MMU v3. Prefetch buffers must be controled with care because there are some restrictions in H/W design. The interface and implementation to initiate prefetch buffers will be prepared later. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 16 1 file changed, 16 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 0d26aeb..647fc46 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -244,13 +244,6 @@ static void __sysmmu_set_ptbase(void __iomem *sfrbase, __sysmmu_tlb_invalidate(sfrbase); } -static void __sysmmu_set_prefbuf(void __iomem *sfrbase, unsigned long base, - unsigned long size, int idx) -{ - __raw_writel(base, sfrbase + REG_PB0_SADDR + idx * 8); - __raw_writel(size - 1 + base, sfrbase + REG_PB0_EADDR + idx * 8); -} - static void __set_fault_handler(struct sysmmu_drvdata *data, sysmmu_fault_handler_t handler) { @@ -424,15 +417,6 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data, for (i = 0; i data-nsfrs; i++) { __sysmmu_set_ptbase(data-sfrbases[i], pgtable); - - if ((readl(data-sfrbases[i] + REG_MMU_VERSION) 28) == 3) { - /* System MMU version is 3.x */ - __raw_writel((1 12) | (2 28), - data-sfrbases[i] + REG_MMU_CFG); - __sysmmu_set_prefbuf(data-sfrbases[i], 0, -1, 0); - __sysmmu_set_prefbuf(data-sfrbases[i], 0, -1, 1); - } - __raw_writel(CTRL_ENABLE, data-sfrbases[i] + REG_MMU_CTRL); } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 07/27] iommu/exynos: always enable runtime PM
Checking if the probing device has a parent device was just to discover if the probing device is involved in a power domain when the power domain controlled by Samsung's custom implementation. Since generic IO power domain is applied, it is required to remove the condition to see if the probing device has a parent device. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index bee1bb1..8dc7031 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -632,8 +632,7 @@ static int exynos_sysmmu_probe(struct platform_device *pdev) __set_fault_handler(data, default_fault_handler); - if (dev-parent) - pm_runtime_enable(dev); + pm_runtime_enable(dev); dev_dbg(dev, (%s) Initialized\n, data-dbgname); return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 06/27] iommu/exynos: allocate lv2 page table from own slab
Since kmalloc() does not guarantee that the allignment of 1KiB when it allocates 1KiB, it is required to allocate lv2 page table from own slab that guarantees alignment of 1KiB Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 34 -- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 647fc46..bee1bb1 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -100,6 +100,8 @@ #define REG_PB1_SADDR 0x054 #define REG_PB1_EADDR 0x058 +static struct kmem_cache *lv2table_kmem_cache; + static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova) { return pgtable + lv1ent_offset(iova); @@ -726,7 +728,8 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain) for (i = 0; i NUM_LV1ENTRIES; i++) if (lv1ent_page(priv-pgtable + i)) - kfree(__va(lv2table_base(priv-pgtable + i))); + kmem_cache_free(lv2table_kmem_cache, + __va(lv2table_base(priv-pgtable + i))); free_pages((unsigned long)priv-pgtable, 2); free_pages((unsigned long)priv-lv2entcnt, 1); @@ -825,7 +828,7 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova, if (lv1ent_fault(sent)) { unsigned long *pent; - pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC); + pent = kmem_cache_zalloc(lv2table_kmem_cache, GFP_ATOMIC); BUG_ON((unsigned long)pent (LV2TABLE_SIZE - 1)); if (!pent) return ERR_PTR(-ENOMEM); @@ -855,8 +858,7 @@ static int lv1set_section(unsigned long *sent, unsigned long iova, return -EADDRINUSE; } - kfree(page_entry(sent, 0)); - + kmem_cache_free(lv2table_kmem_cache, page_entry(sent, 0)); *pgcnt = 0; } @@ -1061,11 +1063,31 @@ static int __init exynos_iommu_init(void) { int ret; + lv2table_kmem_cache = kmem_cache_create(exynos-iommu-lv2table, + LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL); + if (!lv2table_kmem_cache) { + pr_err(%s: Failed to create kmem cache\n, __func__); + return -ENOMEM; + } + ret = platform_driver_register(exynos_sysmmu_driver); + if (ret) { + pr_err(%s: Failed to register driver\n, __func__); + goto err_reg_driver; + } - if (ret == 0) - bus_set_iommu(platform_bus_type, exynos_iommu_ops); + ret = bus_set_iommu(platform_bus_type, exynos_iommu_ops); + if (ret) { + pr_err(%s: Failed to register exynos-iommu driver.\n, + __func__); + goto err_set_iommu; + } + return 0; +err_set_iommu: + platform_driver_unregister(exynos_sysmmu_driver); +err_reg_driver: + kmem_cache_destroy(lv2table_kmem_cache); return ret; } subsys_initcall(exynos_iommu_init); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 09/27] iommu/exynos: remove dbgname from drvdata of a System MMU
This patch removes dbgname member from sysmmu_drvdata structure. Kernel message for debugging already has the name of a single System MMU node. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 32 +--- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index a4499b2..36e6b73 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -170,7 +170,6 @@ struct sysmmu_drvdata { struct list_head node; /* entry of exynos_iommu_domain.clients */ struct device *sysmmu; /* System MMU's device descriptor */ struct device *dev; /* Owner of system MMU */ - char *dbgname; void __iomem *sfrbase; struct clk *clk; int activations; @@ -321,8 +320,8 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) if (!ret (itype != SYSMMU_FAULT_UNKNOWN)) __raw_writel(1 itype, data-sfrbase + REG_INT_CLEAR); else - dev_dbg(data-sysmmu, (%s) %s is not handled.\n, - data-dbgname, sysmmu_fault_name[itype]); + dev_dbg(data-sysmmu, %s is not handled.\n, + sysmmu_fault_name[itype]); if (itype != SYSMMU_FAULT_UNKNOWN) sysmmu_unblock(data-sfrbase); @@ -354,10 +353,10 @@ finish: write_unlock_irqrestore(data-lock, flags); if (disabled) - dev_dbg(data-sysmmu, (%s) Disabled\n, data-dbgname); + dev_dbg(data-sysmmu, Disabled\n); else - dev_dbg(data-sysmmu, (%s) %d times left to be disabled\n, - data-dbgname, data-activations); + dev_dbg(data-sysmmu, %d times left to be disabled\n, + data-activations); return disabled; } @@ -384,7 +383,7 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data, ret = 1; } - dev_dbg(data-sysmmu, (%s) Already enabled\n, data-dbgname); + dev_dbg(data-sysmmu, Already enabled\n); goto finish; } @@ -399,7 +398,7 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data, data-domain = domain; - dev_dbg(data-sysmmu, (%s) Enabled\n, data-dbgname); + dev_dbg(data-sysmmu, Enabled\n); finish: write_unlock_irqrestore(data-lock, flags); @@ -415,16 +414,15 @@ int exynos_sysmmu_enable(struct device *dev, unsigned long pgtable) ret = pm_runtime_get_sync(data-sysmmu); if (ret 0) { - dev_dbg(data-sysmmu, (%s) Failed to enable\n, data-dbgname); + dev_dbg(data-sysmmu, Failed to enable\n); return ret; } ret = __exynos_sysmmu_enable(data, pgtable, NULL); if (WARN_ON(ret 0)) { pm_runtime_put(data-sysmmu); - dev_err(data-sysmmu, - (%s) Already enabled with page table %#lx\n, - data-dbgname, data-pgtable); + dev_err(data-sysmmu, Already enabled with page table %#lx\n, + data-pgtable); } else { data-dev = dev; } @@ -474,9 +472,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, sysmmu_unblock(data-sfrbase); } } else { - dev_dbg(data-sysmmu, - (%s) Disabled. Skipping invalidating TLB.\n, - data-dbgname); + dev_dbg(data-sysmmu, Disabled. Skipping invalidating TLB.\n); } read_unlock_irqrestore(data-lock, flags); @@ -495,9 +491,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev) sysmmu_unblock(data-sfrbase); } } else { - dev_dbg(data-sysmmu, - (%s) Disabled. Skipping invalidating TLB.\n, - data-dbgname); + dev_dbg(data-sysmmu, Disabled. Skipping invalidating TLB.\n); } read_unlock_irqrestore(data-lock, flags); @@ -562,7 +556,7 @@ static int exynos_sysmmu_probe(struct platform_device *pdev) pm_runtime_enable(dev); - dev_dbg(dev, (%s) Initialized\n, data-dbgname); + dev_dbg(dev, Initialized\n); return 0; err_irq: free_irq(platform_get_irq(pdev, 0), data); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 08/27] iommu/exynos: always use a single clock descriptor
System MMU driver is changed to control only a single instance of System MMU at a time. Since a single instance of System MMU has only a single clock descriptor for its clock gating, there is no need to obtain two or more clock descriptors. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 223 ++ 1 file changed, 72 insertions(+), 151 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 8dc7031..a4499b2 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -171,9 +171,8 @@ struct sysmmu_drvdata { struct device *sysmmu; /* System MMU's device descriptor */ struct device *dev; /* Owner of system MMU */ char *dbgname; - int nsfrs; - void __iomem **sfrbases; - struct clk *clk[2]; + void __iomem *sfrbase; + struct clk *clk; int activations; rwlock_t lock; struct iommu_domain *domain; @@ -294,56 +293,39 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) { /* SYSMMU is in blocked when interrupt occurred. */ struct sysmmu_drvdata *data = dev_id; - struct resource *irqres; - struct platform_device *pdev; enum exynos_sysmmu_inttype itype; unsigned long addr = -1; - - int i, ret = -ENOSYS; + int ret = -ENOSYS; read_lock(data-lock); WARN_ON(!is_sysmmu_active(data)); - pdev = to_platform_device(data-sysmmu); - for (i = 0; i (pdev-num_resources / 2); i++) { - irqres = platform_get_resource(pdev, IORESOURCE_IRQ, i); - if (irqres ((int)irqres-start == irq)) - break; - } - - if (i == pdev-num_resources) { + itype = (enum exynos_sysmmu_inttype) + __ffs(__raw_readl(data-sfrbase + REG_INT_STATUS)); + if (WARN_ON(!((itype = 0) (itype SYSMMU_FAULT_UNKNOWN itype = SYSMMU_FAULT_UNKNOWN; - } else { - itype = (enum exynos_sysmmu_inttype) - __ffs(__raw_readl(data-sfrbases[i] + REG_INT_STATUS)); - if (WARN_ON(!((itype = 0) (itype SYSMMU_FAULT_UNKNOWN - itype = SYSMMU_FAULT_UNKNOWN; - else - addr = __raw_readl( - data-sfrbases[i] + fault_reg_offset[itype]); - } + else + addr = __raw_readl(data-sfrbase + fault_reg_offset[itype]); if (data-domain) - ret = report_iommu_fault(data-domain, data-dev, - addr, itype); + ret = report_iommu_fault(data-domain, data-dev, addr, itype); if ((ret == -ENOSYS) data-fault_handler) { unsigned long base = data-pgtable; if (itype != SYSMMU_FAULT_UNKNOWN) - base = __raw_readl( - data-sfrbases[i] + REG_PT_BASE_ADDR); + base = __raw_readl(data-sfrbase + REG_PT_BASE_ADDR); ret = data-fault_handler(itype, base, addr); } if (!ret (itype != SYSMMU_FAULT_UNKNOWN)) - __raw_writel(1 itype, data-sfrbases[i] + REG_INT_CLEAR); + __raw_writel(1 itype, data-sfrbase + REG_INT_CLEAR); else dev_dbg(data-sysmmu, (%s) %s is not handled.\n, data-dbgname, sysmmu_fault_name[itype]); if (itype != SYSMMU_FAULT_UNKNOWN) - sysmmu_unblock(data-sfrbases[i]); + sysmmu_unblock(data-sfrbase); read_unlock(data-lock); @@ -354,20 +336,16 @@ static bool __exynos_sysmmu_disable(struct sysmmu_drvdata *data) { unsigned long flags; bool disabled = false; - int i; write_lock_irqsave(data-lock, flags); if (!set_sysmmu_inactive(data)) goto finish; - for (i = 0; i data-nsfrs; i++) - __raw_writel(CTRL_DISABLE, data-sfrbases[i] + REG_MMU_CTRL); + __raw_writel(CTRL_DISABLE, data-sfrbase + REG_MMU_CTRL); - if (data-clk[1]) - clk_disable(data-clk[1]); - if (data-clk[0]) - clk_disable(data-clk[0]); + if (data-clk) + clk_disable(data-clk); disabled = true; data-pgtable = 0; @@ -393,7 +371,7 @@ finish: static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data, unsigned long pgtable, struct iommu_domain *domain) { - int i, ret = 0; + int ret = 0; unsigned long flags; write_lock_irqsave(data-lock, flags); @@ -410,17 +388,14 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data, goto finish; } - if (data-clk[0]) - clk_enable(data-clk[0]); - if (data-clk[1]) - clk_enable(data-clk[1]); +
[PATCH v11 11/27] clk: exynos: add gate clock descriptions of System MMU
This adds gate clocks of all System MMUs and their master IPs that are not apeared in clk-exynos5250.c and clk-exynos5420.c Also fixes GATE_IP_ACP to 0x18800 and changed GATE_DA to GATE for System MMU clocks in clk-exynos4.c Signed-off-by: Cho KyongHo pullip@samsung.com --- .../devicetree/bindings/clock/exynos5250-clock.txt |3 +++ .../devicetree/bindings/clock/exynos5420-clock.txt |6 +- drivers/clk/samsung/clk-exynos5250.c |5 + drivers/clk/samsung/clk-exynos5420.c | 13 +++-- include/dt-bindings/clock/exynos5250.h |4 include/dt-bindings/clock/exynos5420.h |6 +- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt index 72ce617..67e50ba 100644 --- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt @@ -162,6 +162,9 @@ clock which they consume. g2d 345 mdma0346 smmu_mdma0 347 + smmu_tv 348 + smmu_fimd1 349 + smmu_2d 350 [Clock Muxes] diff --git a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt index 458f347..62dabc3 100644 --- a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt @@ -146,7 +146,8 @@ clock which they consume. hdmi 413 aclk300_disp1420 fimd1421 - smmu_fimd1 422 + smmu_fimd1m0 422 + smmu_fimd1m1 423 aclk166 430 mixer431 aclk266 440 @@ -172,12 +173,15 @@ clock which they consume. mdma0473 aclk333_g2d 480 g2d 481 + smmu_g2d 482 aclk333_432_gscl 490 smmu_3aa 491 smmu_fimcl0 492 smmu_fimcl1 493 smmu_fimcl3 494 fimc_lite3 495 + fimc_lite0 496 + fimc_lite1 497 aclk_g3d 500 g3d 501 smmu_mixer 502 diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index e7ee442..6605733 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -615,6 +615,11 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { GATE(CLK_WDT, wdt, div_aclk66, GATE_IP_PERIS, 19, 0, 0), GATE(CLK_RTC, rtc, div_aclk66, GATE_IP_PERIS, 20, 0, 0), GATE(CLK_TMU, tmu, div_aclk66, GATE_IP_PERIS, 21, 0, 0), + GATE(CLK_SMMU_TV, smmu_tv, mout_aclk200_disp1_sub, + GATE_IP_DISP1, 2, 0, 0), + GATE(CLK_SMMU_FIMD1, smmu_fimd1, mout_aclk200_disp1_sub, + GATE_IP_DISP1, 8, 0, 0), + GATE(CLK_SMMU_2D, smmu_2d, div_aclk200, GATE_IP_ACP, 7, 0, 0), }; static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = { diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 60b2681..b58e4d3 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -82,6 +82,7 @@ #define GATE_BUS_PERIC10x10754 #define GATE_BUS_PERIS00x10760 #define GATE_BUS_PERIS10x10764 +#define GATE_IP_G2D0x08800 #define GATE_IP_GSCL0 0x10910 #define GATE_IP_GSCL1 0x10920 #define GATE_IP_MFC0x1092c @@ -707,6 +708,10 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_GSCL_WB, gscl_wb, aclk300_gscl, GATE_IP_GSCL1, 13, 0, 0), GATE(CLK_SMMU_FIMCL3, smmu_fimcl3,, aclk333_432_gscl, GATE_IP_GSCL1, 16, 0, 0), + GATE(CLK_FIMC_LITE0, fimc_lite0, aclk333_432_gscl, + GATE_IP_GSCL0, 5, 0, 0), + GATE(CLK_FIMC_LITE1, fimc_lite1, aclk333_432_gscl, + GATE_IP_GSCL0, 6, 0, 0), GATE(CLK_FIMC_LITE3, fimc_lite3, aclk333_432_gscl, GATE_IP_GSCL1, 17, 0, 0), @@ -715,8 +720,10 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_DP1, dp1, aclk200_disp1, GATE_IP_DISP1, 4, 0, 0), GATE(CLK_MIXER, mixer, aclk166, GATE_IP_DISP1, 5, 0, 0), GATE(CLK_HDMI, hdmi, aclk200_disp1, GATE_IP_DISP1, 6, 0, 0), - GATE(CLK_SMMU_FIMD1, smmu_fimd1, aclk300_disp1, GATE_IP_DISP1, 8, 0, - 0), + GATE(CLK_SMMU_FIMD1M0, smmu_fimd1m0, aclk300_disp1, GATE_IP_DISP1, + 7, 0, 0), + GATE(CLK_SMMU_FIMD1M1, smmu_fimd1m1, aclk300_disp1, GATE_IP_DISP1, + 8, 0, 0), GATE(CLK_MFC, mfc, aclk333,
[PATCH v11 10/27] iommu/exynos: use managed device helper functions
This patch uses managed device helper functions in the probe(). Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 64 +- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 36e6b73..33b424d 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -499,51 +499,48 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev) static int exynos_sysmmu_probe(struct platform_device *pdev) { - int ret; + int irq, ret; struct device *dev = pdev-dev; struct sysmmu_drvdata *data; struct resource *res; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - dev_dbg(dev, Not enough memory\n); - ret = -ENOMEM; - goto err_alloc; - } + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - dev_dbg(dev, Unable to find IOMEM region\n); - ret = -ENOENT; - goto err_init; + dev_err(dev, Unable to find IOMEM region\n); + return -ENOENT; } - data-sfrbase = ioremap(res-start, resource_size(res)); - if (!data-sfrbase) { - dev_dbg(dev, Unable to map IOMEM @ PA:%#x\n, res-start); - ret = -ENOENT; - goto err_res; - } + data-sfrbase = devm_ioremap_resource(dev, res); + if (IS_ERR(data-sfrbase)) + return PTR_ERR(data-sfrbase); - ret = platform_get_irq(pdev, 0); - if (ret = 0) { + irq = platform_get_irq(pdev, 0); + if (irq = 0) { dev_dbg(dev, Unable to find IRQ resource\n); - goto err_irq; + return irq; } - ret = request_irq(ret, exynos_sysmmu_irq, 0, + ret = devm_request_irq(dev, irq, exynos_sysmmu_irq, 0, dev_name(dev), data); if (ret) { - dev_dbg(dev, Unabled to register interrupt handler\n); - goto err_irq; + dev_err(dev, Unabled to register handler of irq %d\n, irq); + return ret; } - if (dev_get_platdata(dev)) { - data-clk = clk_get(dev, sysmmu); - if (IS_ERR(data-clk)) { - data-clk = NULL; - dev_dbg(dev, No clock descriptor registered\n); - } + data-clk = devm_clk_get(dev, sysmmu); + if (IS_ERR(data-clk)) { + dev_info(dev, No gate clock found!\n); + data-clk = NULL; + } + + ret = clk_prepare(data-clk); + if (ret) { + dev_err(dev, Failed to prepare clk\n); + return ret; } data-sysmmu = dev; @@ -556,17 +553,8 @@ static int exynos_sysmmu_probe(struct platform_device *pdev) pm_runtime_enable(dev); - dev_dbg(dev, Initialized\n); + dev_dbg(dev, Probed and initialized\n); return 0; -err_irq: - free_irq(platform_get_irq(pdev, 0), data); -err_res: - iounmap(data-sfrbase); -err_init: - kfree(data); -err_alloc: - dev_err(dev, Failed to initialize\n); - return ret; } static struct platform_driver exynos_sysmmu_driver = { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 12/27] ARM: dts: Add description of System MMU of Exynos SoCs
This patch adds dts entries for the System MMU devices found on Exynos4 and Exynos5 SoC series and the System MMU binding documentation. CC: Rob Herring robherri...@gmail.com CC: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Cho KyongHo pullip@samsung.com --- .../bindings/iommu/samsung,exynos4210-sysmmu.txt | 86 +++ arch/arm/boot/dts/exynos4.dtsi | 107 arch/arm/boot/dts/exynos4210.dtsi | 23 +- arch/arm/boot/dts/exynos4x12.dtsi | 77 +- arch/arm/boot/dts/exynos5250.dtsi | 266 +++- arch/arm/boot/dts/exynos5420.dtsi | 205 ++- 6 files changed, 758 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt diff --git a/Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt b/Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt new file mode 100644 index 000..e4417bb --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt @@ -0,0 +1,86 @@ +Samsung Exynos IOMMU H/W, System MMU (System Memory Management Unit) + +Samsung's Exynos architecture contains System MMUs that enables scattered +physical memory chunks visible as a contiguous region to DMA-capable peripheral +devices like MFC, FIMC, FIMD, GScaler, FIMC-IS and so forth. + +System MMU is an IOMMU and supports identical translation table format to +ARMv7 translation tables with minimum set of page properties including access +permissions, shareability and security protection. In addition, System MMU has +another capabilities like L2 TLB or block-fetch buffers to minimize translation +latency. + +System MMUs are in many to one relation with peripheral devices, i.e. single +peripheral device might have multiple System MMUs (usually one for each bus +master), but one System MMU can handle transactions from only one peripheral +device. The relation between a System MMU and the peripheral device needs to be +defined in device node of the peripheral device. + +MFC in all Exynos SoCs and FIMD, M2M Scalers and G2D in Exynos5420 has 2 System +MMUs. +* MFC has one System MMU on its left and right bus. +* FIMD in Exynos5420 has one System MMU for window 0 and 4, the other system MMU + for window 1, 2 and 3. +* M2M Scalers and G2D in Exynos5420 has one System MMU on the read channel and + the other System MMU on the write channel. +The drivers must consider how to handle those System MMUs. One of the idea is +to implement child devices or sub-devices which are the client devices of the +System MMU. + +Required properties: +- compatible: Should be one of: + samsung,sysmmu-v1 + samsung,sysmmu-v2 + samsung,sysmmu-v3.1 + samsung,sysmmu-v3.2 + samsung,sysmmu-v3.3 + +- reg: A tuple of base address and size of System MMU registers. +- interrupt-parent: The phandle of the interrupt controller of System MMU +- interrupts: An interrupt specifier for interrupt signal of System MMU, + according to the format defined by a particular interrupt + controller. +- clock-names: Should be sysmmu if the System MMU is needed to gate its clock. + Please refer to the following documents: + Documentation/devicetree/bindings/clock/clock-bindings.txt + Documentation/devicetree/bindings/clock/exynos4-clock.txt + Documentation/devicetree/bindings/clock/exynos5250-clock.txt + Documentation/devicetree/bindings/clock/exynos5420-clock.txt + Optional master if the clock to the System MMU is gated by + another gate clock other than sysmmu. The System MMU driver + sets master the parent of sysmmu. + Exynos4 SoCs, there needs no master clockj. + Exynos5 SoCs, some System MMUs must have master clocks. +- clocks: Required if the System MMU is needed to gate its clock. + Please refer to the documents listed above. +- samsung,power-domain: Required if the System MMU is needed to gate its power. + Please refer to the following document: + Documentation/devicetree/bindings/arm/exynos/power_domain.txt +- mmu-masters: A phandle to device nodes representing the master for which + the System MMU can provide a translation. Any additional values + after the phandle will be ignored because a System MMU never + have two or more masters. #stream-id-cells specified in the + master's node will be also ignored. + If more than one phandle is specified, only the first phandle + will be treated. + +Examples: + gsc_0: gsc@13e0 { + compatible = samsung,exynos5-gsc; + reg = 0x13e0 0x1000; + interrupts = 0 85 0; + samsung,power-domain =
[PATCH v11 16/27] iommu/exynos: remove custom fault handler
This commit removes custom fault handler. The device drivers that need to register fault handler can register with iommu_set_fault_handler(). CC: Grant Grundler grund...@chromium.org Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 80 +- 1 file changed, 24 insertions(+), 56 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index cef62d0..3458349 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -136,16 +136,6 @@ enum exynos_sysmmu_inttype { SYSMMU_FAULTS_NUM }; -/* - * @itype: type of fault. - * @pgtable_base: the physical address of page table base. This is 0 if @itype - *is SYSMMU_BUSERROR. - * @fault_addr: the device (virtual) address that the System MMU tried to - * translated. This is 0 if @itype is SYSMMU_BUSERROR. - */ -typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype, - unsigned long pgtable_base, unsigned long fault_addr); - static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = { REG_PAGE_FAULT_ADDR, REG_AR_FAULT_ADDR, @@ -187,7 +177,6 @@ struct sysmmu_drvdata { int activations; rwlock_t lock; struct iommu_domain *domain; - sysmmu_fault_handler_t fault_handler; unsigned long pgtable; }; @@ -256,34 +245,17 @@ static void __sysmmu_set_ptbase(void __iomem *sfrbase, __sysmmu_tlb_invalidate(sfrbase); } -static void __set_fault_handler(struct sysmmu_drvdata *data, - sysmmu_fault_handler_t handler) -{ - unsigned long flags; - - write_lock_irqsave(data-lock, flags); - data-fault_handler = handler; - write_unlock_irqrestore(data-lock, flags); -} - -void exynos_sysmmu_set_fault_handler(struct device *dev, - sysmmu_fault_handler_t handler) -{ - struct sysmmu_drvdata *data = dev_get_drvdata(dev-archdata.iommu); - - __set_fault_handler(data, handler); -} - -static int default_fault_handler(enum exynos_sysmmu_inttype itype, -unsigned long pgtable_base, unsigned long fault_addr) +static void show_fault_information(const char *name, + enum exynos_sysmmu_inttype itype, + unsigned long pgtable_base, unsigned long fault_addr) { unsigned long *ent; if ((itype = SYSMMU_FAULTS_NUM) || (itype SYSMMU_PAGEFAULT)) itype = SYSMMU_FAULT_UNKNOWN; - pr_err(%s occurred at 0x%lx(Page table base: 0x%lx)\n, - sysmmu_fault_name[itype], fault_addr, pgtable_base); + pr_err(%s occurred at 0x%lx by %s(Page table base: 0x%lx)\n, + sysmmu_fault_name[itype], fault_addr, name, pgtable_base); ent = section_entry(__va(pgtable_base), fault_addr); pr_err(\tLv1 entry: 0x%lx\n, *ent); @@ -292,12 +264,6 @@ static int default_fault_handler(enum exynos_sysmmu_inttype itype, ent = page_entry(ent, fault_addr); pr_err(\t Lv2 entry: 0x%lx\n, *ent); } - - pr_err(Generating Kernel OOPS... because it is unrecoverable.\n); - - BUG(); - - return 0; } static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) @@ -320,24 +286,28 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) else addr = __raw_readl(data-sfrbase + fault_reg_offset[itype]); - if (data-domain) - ret = report_iommu_fault(data-domain, data-dev, addr, itype); - - if ((ret == -ENOSYS) data-fault_handler) { - unsigned long base = data-pgtable; - if (itype != SYSMMU_FAULT_UNKNOWN) - base = __raw_readl(data-sfrbase + REG_PT_BASE_ADDR); - ret = data-fault_handler(itype, base, addr); + if (itype == SYSMMU_FAULT_UNKNOWN) { + pr_err(%s: Fault is not occurred by System MMU '%s'!\n, + __func__, dev_name(data-sysmmu)); + pr_err(%s: Please check if IRQ is correctly configured.\n, + __func__); + BUG(); + } else { + unsigned long base = + __raw_readl(data-sfrbase + REG_PT_BASE_ADDR); + show_fault_information(dev_name(data-sysmmu), + itype, base, addr); + if (data-domain) + ret = report_iommu_fault(data-domain, + data-dev, addr, itype); } - if (!ret (itype != SYSMMU_FAULT_UNKNOWN)) - __raw_writel(1 itype, data-sfrbase + REG_INT_CLEAR); - else - dev_dbg(data-sysmmu, %s is not handled.\n, - sysmmu_fault_name[itype]); + /* fault is not recovered by fault handler */ + BUG_ON(ret != 0); - if (itype !=
[PATCH v11 17/27] iommu/exynos: remove calls to Runtime PM API functions
Runtime power management by exynos-iommu driver independently from master H/W's runtime pm is not useful for power saving since attaching master H/W in probing time turns on its local power endlessly. Thus this removes runtime pm API calls. Runtime PM support is added in the following commits to exynos-iommu driver. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 369 +++--- 1 file changed, 238 insertions(+), 131 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 3458349..6834556 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -27,6 +27,8 @@ #include linux/memblock.h #include linux/export.h #include linux/of.h +#include linux/of_platform.h +#include linux/notifier.h #include asm/cacheflush.h #include asm/pgtable.h @@ -111,6 +113,8 @@ #define __master_clk_enable(data) __clk_gate_ctrl(data, clk_master, en) #define __master_clk_disable(data) __clk_gate_ctrl(data, clk_master, dis) +#define has_sysmmu(dev)(dev-archdata.iommu != NULL) + static struct kmem_cache *lv2table_kmem_cache; static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova) @@ -159,6 +163,16 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = { UNKNOWN FAULT }; +/* attached to dev.archdata.iommu of the master device */ +struct exynos_iommu_owner { + struct list_head client; /* entry of exynos_iommu_domain.clients */ + struct device *dev; + struct device *sysmmu; + struct iommu_domain *domain; + void *vmm_data; /* IO virtual memory manager's data */ + spinlock_t lock;/* Lock to preserve consistency of System MMU */ +}; + struct exynos_iommu_domain { struct list_head clients; /* list of sysmmu_drvdata.node */ unsigned long *pgtable; /* lv1 page table, 16KB */ @@ -168,9 +182,8 @@ struct exynos_iommu_domain { }; struct sysmmu_drvdata { - struct list_head node; /* entry of exynos_iommu_domain.clients */ struct device *sysmmu; /* System MMU's device descriptor */ - struct device *dev; /* Owner of system MMU */ + struct device *master; /* Owner of system MMU */ void __iomem *sfrbase; struct clk *clk; struct clk *clk_master; @@ -239,7 +252,6 @@ static void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase, static void __sysmmu_set_ptbase(void __iomem *sfrbase, unsigned long pgd) { - __raw_writel(0x1, sfrbase + REG_MMU_CFG); /* 16KB LV1, LRU */ __raw_writel(pgd, sfrbase + REG_PT_BASE_ADDR); __sysmmu_tlb_invalidate(sfrbase); @@ -299,7 +311,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) itype, base, addr); if (data-domain) ret = report_iommu_fault(data-domain, - data-dev, addr, itype); + data-master, addr, itype); } /* fault is not recovered by fault handler */ @@ -316,116 +328,148 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static bool __exynos_sysmmu_disable(struct sysmmu_drvdata *data) +static void __sysmmu_disable_nocount(struct sysmmu_drvdata *data) { - unsigned long flags; - bool disabled = false; - - write_lock_irqsave(data-lock, flags); - - if (!set_sysmmu_inactive(data)) - goto finish; - - __master_clk_enable(data); + clk_enable(data-clk_master); __raw_writel(CTRL_DISABLE, data-sfrbase + REG_MMU_CTRL); + __raw_writel(0, data-sfrbase + REG_MMU_CFG); __sysmmu_clk_disable(data); __master_clk_disable(data); +} - disabled = true; - data-pgtable = 0; - data-domain = NULL; -finish: - write_unlock_irqrestore(data-lock, flags); +static bool __sysmmu_disable(struct sysmmu_drvdata *data) +{ + bool disabled; + unsigned long flags; + + write_lock_irqsave(data-lock, flags); + + disabled = set_sysmmu_inactive(data); + + if (disabled) { + data-pgtable = 0; + data-domain = NULL; + + __sysmmu_disable_nocount(data); - if (disabled) dev_dbg(data-sysmmu, Disabled\n); - else - dev_dbg(data-sysmmu, %d times left to be disabled\n, + } else { + dev_dbg(data-sysmmu, %d times left to disable\n, data-activations); + } + + write_unlock_irqrestore(data-lock, flags); return disabled; } -/* __exynos_sysmmu_enable: Enables System MMU - * - * returns -error if an error occurred and System MMU is not enabled, - * 0 if the System MMU has been just enabled and 1 if System MMU was already - * enabled before. - */ -static
[PATCH v11 18/27] iommu/exynos: turn on useful configuration options
This turns on FLPD_CACHE, ACGEN and SYSSEL. FLPD_CACHE is a cache of 1st level page table entries that contains the address of a 2nd level page table to reduce latency of page table walking. ACGEN is architectural clock gating that gates clocks by System MMU itself if it is not active. Note that ACGEN is different from clock gating by the CPU. ACGEN just gates clocks to the internal logic of System MMU while clock gating by the CPU gates clocks to the System MMU. SYSSEL selects System MMU version in some Exynos SoCs. Some Exynos SoCs have an option to select System MMU versions exclusively because the SoCs adopts new System MMU version experimentally. This also always selects LRU as TLB replacement policy. Selecting TLB replacement policy is deprecated from System MMU 3.2. TLB in System MMU 3.3 has single TLB replacement policy, LRU. The bit of MMU_CFG selecting TLB replacement policy is remained as reserved. QoS value of page table walking is set to 15 (highst value). System MMU 3.3 can inherit QoS value of page table walking from its master H/W's transaction. This new feature is enabled by default and QoS value written to MMU_CFG is ignored. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 52 +- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 6834556..9037da0 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -82,6 +82,13 @@ #define CTRL_BLOCK 0x7 #define CTRL_DISABLE 0x0 +#define CFG_LRU0x1 +#define CFG_QOS(n) ((n 0xF) 7) +#define CFG_MASK 0x0150 /* Selecting bit 0-15, 20, 22 and 24 */ +#define CFG_ACGEN (1 24) /* System MMU 3.3 only */ +#define CFG_SYSSEL (1 22) /* System MMU 3.2 only */ +#define CFG_FLPDCACHE (1 20) /* System MMU 3.2+ only */ + #define REG_MMU_CTRL 0x000 #define REG_MMU_CFG0x004 #define REG_MMU_STATUS 0x008 @@ -98,6 +105,12 @@ #define REG_MMU_VERSION0x034 +#define MMU_MAJ_VER(val) ((val) 7) +#define MMU_MIN_VER(val) ((val) 0x7F) +#define MMU_RAW_VER(reg) (((reg) 21) ((1 11) - 1)) /* 11 bits */ + +#define MAKE_MMU_VER(maj, min) maj) 0xF) 7) | ((min) 0x7F)) + #define REG_PB0_SADDR 0x04C #define REG_PB0_EADDR 0x050 #define REG_PB1_SADDR 0x054 @@ -217,6 +230,29 @@ static void sysmmu_unblock(void __iomem *sfrbase) __raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL); } +static unsigned int __raw_sysmmu_version(struct sysmmu_drvdata *data) +{ + return MMU_RAW_VER(__raw_readl(data-sfrbase + REG_MMU_VERSION)); +} + +static unsigned int __sysmmu_version(struct sysmmu_drvdata *data, +unsigned int *minor) +{ + unsigned int ver = 0; + + ver = __raw_sysmmu_version(data); + if (ver MAKE_MMU_VER(3, 3)) { + dev_err(data-sysmmu, %s: version(%d.%d) is higher than 3.3\n, + __func__, MMU_MAJ_VER(ver), MMU_MIN_VER(ver)); + BUG(); + } + + if (minor) + *minor = MMU_MIN_VER(ver); + + return MMU_MAJ_VER(ver); +} + static bool sysmmu_block(void __iomem *sfrbase) { int i = 120; @@ -367,7 +403,21 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data) static void __sysmmu_init_config(struct sysmmu_drvdata *data) { - unsigned long cfg = 0; + unsigned long cfg = CFG_LRU | CFG_QOS(15); + int maj, min = 0; + + maj = __sysmmu_version(data, min); + if (maj == 3) { + if (min = 2) { + cfg |= CFG_FLPDCACHE; + if (min == 3) { + cfg |= CFG_ACGEN; + cfg = ~CFG_LRU; + } else { + cfg |= CFG_SYSSEL; + } + } + } __raw_writel(cfg, data-sfrbase + REG_MMU_CFG); } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 20/27] iommu/exynos: allow having multiple System MMUs for a master H/W
Some master device descriptor like fimc-is which is an abstraction of very complex H/W may have multiple System MMUs. For those devices, the design of the link between System MMU and its master H/W is needed to be reconsidered. A link structure, sysmmu_list_data is introduced that provides a link to master H/W and that has a pointer to the device descriptor of a System MMU. Given a device descriptor of a master H/W, it is possible to traverse all System MMUs that must be controlled along with the master H/W. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 534 ++ 1 file changed, 333 insertions(+), 201 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 84ba29a..7489343 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -128,6 +128,10 @@ #define __master_clk_disable(data) __clk_gate_ctrl(data, clk_master, dis) #define has_sysmmu(dev)(dev-archdata.iommu != NULL) +#define for_each_sysmmu_list(dev, list_data) \ + list_for_each_entry(list_data, \ + ((struct exynos_iommu_owner *)dev-archdata.iommu)-mmu_list, \ + entry) static struct kmem_cache *lv2table_kmem_cache; @@ -181,7 +185,7 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = { struct exynos_iommu_owner { struct list_head client; /* entry of exynos_iommu_domain.clients */ struct device *dev; - struct device *sysmmu; + struct list_head mmu_list; /* list of sysmmu_list_data.entry */ struct iommu_domain *domain; void *vmm_data; /* IO virtual memory manager's data */ spinlock_t lock;/* Lock to preserve consistency of System MMU */ @@ -195,6 +199,11 @@ struct exynos_iommu_domain { spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */ }; +struct sysmmu_list_data { + struct list_head entry; /* entry of exynos_iommu_owner.mmu_list */ + struct device *sysmmu; +}; + struct sysmmu_drvdata { struct device *sysmmu; /* System MMU's device descriptor */ struct device *master; /* Owner of system MMU */ @@ -205,6 +214,7 @@ struct sysmmu_drvdata { rwlock_t lock; struct iommu_domain *domain; bool runtime_active; + bool suspended; unsigned long pgtable; }; @@ -471,28 +481,39 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data, } /* __exynos_sysmmu_enable: Enables System MMU - * - * returns -error if an error occurred and System MMU is not enabled, - * 0 if the System MMU has been just enabled and 1 if System MMU was already - * enabled before. - */ +* +* returns -error if an error occurred and System MMU is not enabled, +* 0 if the System MMU has been just enabled and 1 if System MMU was already +* enabled before. +*/ static int __exynos_sysmmu_enable(struct device *dev, unsigned long pgtable, struct iommu_domain *domain) { int ret = 0; unsigned long flags; struct exynos_iommu_owner *owner = dev-archdata.iommu; - struct sysmmu_drvdata *data; + struct sysmmu_list_data *list; BUG_ON(!has_sysmmu(dev)); spin_lock_irqsave(owner-lock, flags); - data = dev_get_drvdata(owner-sysmmu); - - ret = __sysmmu_enable(data, pgtable, domain); - if (ret = 0) + for_each_sysmmu_list(dev, list) { + struct sysmmu_drvdata *data = dev_get_drvdata(list-sysmmu); data-master = dev; + ret = __sysmmu_enable(data, pgtable, domain); + if (ret 0) { + struct sysmmu_list_data *iter; + for_each_sysmmu_list(dev, iter) { + if (iter-sysmmu == list-sysmmu) + break; + data = dev_get_drvdata(iter-sysmmu); + __sysmmu_disable(data); + data-master = NULL; + } + break; + } + } spin_unlock_irqrestore(owner-lock, flags); @@ -511,17 +532,19 @@ static bool exynos_sysmmu_disable(struct device *dev) unsigned long flags; bool disabled = true; struct exynos_iommu_owner *owner = dev-archdata.iommu; - struct sysmmu_drvdata *data; + struct sysmmu_list_data *list; BUG_ON(!has_sysmmu(dev)); spin_lock_irqsave(owner-lock, flags); - data = dev_get_drvdata(owner-sysmmu); - - disabled = __sysmmu_disable(data); - if (disabled) - data-master = NULL; + /* Every call to __sysmmu_disable() must return same result */ + for_each_sysmmu_list(dev, list) { + struct sysmmu_drvdata *data = dev_get_drvdata(list-sysmmu); +
[PATCH v11 19/27] iommu/exynos: add support for power management subsystems.
This adds support for Suspend to RAM and Runtime Power Management. Since System MMU is located in the same local power domain of its master H/W, System MMU must be initialized before it is working if its power domain was ever turned off. TLB invalidation according to unmapping on page tables must also be performed while power domain is turned on. This patch ensures that resume and runtime_resume(restore_state) functions in this driver is called before the calls to resume and runtime_resume callback functions in the drivers of master H/Ws. Likewise, suspend and runtime_suspend(save_state) functions in this driver is called after the calls to suspend and runtime_suspend in the drivers of master H/Ws. In order to get benefit of this support, the master H/W and its System MMU must resides in the same power domain in terms of Linux kernel. If a master H/W does not use generic I/O power domain, its driver must call iommu_attach_device() after its local power domain is turned on, iommu_detach_device before turned off. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 220 ++ 1 file changed, 201 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 9037da0..84ba29a 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -28,6 +28,7 @@ #include linux/export.h #include linux/of.h #include linux/of_platform.h +#include linux/pm_domain.h #include linux/notifier.h #include asm/cacheflush.h @@ -203,6 +204,7 @@ struct sysmmu_drvdata { int activations; rwlock_t lock; struct iommu_domain *domain; + bool runtime_active; unsigned long pgtable; }; @@ -388,7 +390,8 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data) data-pgtable = 0; data-domain = NULL; - __sysmmu_disable_nocount(data); + if (data-runtime_active) + __sysmmu_disable_nocount(data); dev_dbg(data-sysmmu, Disabled\n); } else { @@ -449,7 +452,8 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data, data-pgtable = pgtable; data-domain = domain; - __sysmmu_enable_nocount(data); + if (data-runtime_active) + __sysmmu_enable_nocount(data); dev_dbg(data-sysmmu, Enabled\n); } else { @@ -534,13 +538,11 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, data = dev_get_drvdata(owner-sysmmu); read_lock_irqsave(data-lock, flags); - if (is_sysmmu_active(data)) { - unsigned int maj; + if (is_sysmmu_active(data) data-runtime_active) { unsigned int num_inv = 1; __master_clk_enable(data); - maj = __raw_readl(data-sfrbase + REG_MMU_VERSION); /* * L2TLB invalidation required * 4KB page: 1 invalidation @@ -551,7 +553,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, * 1MB page can be cached in one of all sets. * 64KB page can be one of 16 consecutive sets. */ - if ((maj 28) == 2) /* major version number */ + if (__sysmmu_version(data, NULL) == 2) /* major version number */ num_inv = min_t(unsigned int, size / PAGE_SIZE, 64); if (sysmmu_block(data-sfrbase)) { @@ -576,7 +578,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev) data = dev_get_drvdata(owner-sysmmu); read_lock_irqsave(data-lock, flags); - if (is_sysmmu_active(data)) { + if (is_sysmmu_active(data) data-runtime_active) { __master_clk_enable(data); if (sysmmu_block(data-sfrbase)) { __sysmmu_tlb_invalidate(data-sfrbase); @@ -677,11 +679,40 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); pm_runtime_enable(dev); + data-runtime_active = !pm_runtime_enabled(dev); dev_dbg(dev, Probed and initialized\n); return 0; } +#ifdef CONFIG_PM_SLEEP +static int sysmmu_suspend(struct device *dev) +{ + struct sysmmu_drvdata *data = dev_get_drvdata(dev); + unsigned long flags; + read_lock_irqsave(data-lock, flags); + if (is_sysmmu_active(data) + (!pm_runtime_enabled(dev) || data-runtime_active)) + __sysmmu_disable_nocount(data); + read_unlock_irqrestore(data-lock, flags); + return 0; +} + +static int sysmmu_resume(struct device *dev) +{ + struct sysmmu_drvdata *data = dev_get_drvdata(dev); + unsigned long flags; + read_lock_irqsave(data-lock, flags); + if (is_sysmmu_active(data) +
[PATCH v11 14/27] iommu/exynos: gating clocks of master H/W
This patch gates clocks of master H/W as well as clocks of System MMU if master clocks are specified. Some Exynos SoCs (i.e. GScalers in Exynos5250) have dependencies in the gating clocks of master H/W and its System MMU. If a H/W is the case, accessing control registers of System MMU is prohibited unless both of the gating clocks of System MMU and its master H/W. CC: Tomasz Figa t.f...@samsung.com Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 35 ++- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 34feb04..71e77f1 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -173,6 +173,7 @@ struct sysmmu_drvdata { struct device *dev; /* Owner of system MMU */ void __iomem *sfrbase; struct clk *clk; + struct clk *clk_master; int activations; rwlock_t lock; struct iommu_domain *domain; @@ -301,6 +302,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) WARN_ON(!is_sysmmu_active(data)); + clk_enable(data-clk_master); itype = (enum exynos_sysmmu_inttype) __ffs(__raw_readl(data-sfrbase + REG_INT_STATUS)); if (WARN_ON(!((itype = 0) (itype SYSMMU_FAULT_UNKNOWN @@ -327,6 +329,8 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) if (itype != SYSMMU_FAULT_UNKNOWN) sysmmu_unblock(data-sfrbase); + clk_disable(data-clk_master); + read_unlock(data-lock); return IRQ_HANDLED; @@ -342,10 +346,12 @@ static bool __exynos_sysmmu_disable(struct sysmmu_drvdata *data) if (!set_sysmmu_inactive(data)) goto finish; + clk_enable(data-clk_master); + __raw_writel(CTRL_DISABLE, data-sfrbase + REG_MMU_CTRL); - if (data-clk) - clk_disable(data-clk); + clk_disable(data-clk); + clk_disable(data-clk_master); disabled = true; data-pgtable = 0; @@ -388,15 +394,17 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data, goto finish; } - if (data-clk) - clk_enable(data-clk); - data-pgtable = pgtable; + clk_enable(data-clk_master); + clk_enable(data-clk); + __sysmmu_set_ptbase(data-sfrbase, pgtable); __raw_writel(CTRL_ENABLE, data-sfrbase + REG_MMU_CTRL); + clk_disable(data-clk_master); + data-domain = domain; dev_dbg(data-sysmmu, Enabled\n); @@ -453,6 +461,9 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, if (is_sysmmu_active(data)) { unsigned int maj; unsigned int num_inv = 1; + + clk_enable(data-clk_master); + maj = __raw_readl(data-sfrbase + REG_MMU_VERSION); /* * L2TLB invalidation required @@ -472,6 +483,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, num_inv); sysmmu_unblock(data-sfrbase); } + clk_disable(data-clk_master); } else { dev_dbg(data-sysmmu, Disabled. Skipping invalidating TLB.\n); } @@ -487,10 +499,12 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev) read_lock_irqsave(data-lock, flags); if (is_sysmmu_active(data)) { + clk_enable(data-clk_master); if (sysmmu_block(data-sfrbase)) { __sysmmu_tlb_invalidate(data-sfrbase); sysmmu_unblock(data-sfrbase); } + clk_disable(data-clk_master); } else { dev_dbg(data-sysmmu, Disabled. Skipping invalidating TLB.\n); } @@ -544,6 +558,17 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev) return ret; } + data-clk_master = devm_clk_get(dev, master); + if (IS_ERR(data-clk_master)) + data-clk_master = NULL; + + ret = clk_prepare(data-clk_master); + if (ret) { + clk_unprepare(data-clk); + dev_err(dev, Failed to prepare master's clk\n); + return ret; + } + data-sysmmu = dev; rwlock_init(data-lock); INIT_LIST_HEAD(data-node); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 21/27] iommu/exynos: change rwlock to spinlock
Since acquiring read_lock is not more frequent than write_lock, it is not beneficial to use rwlock, this commit changes rwlock to spinlock. Reviewed-by: Grant Grundler grund...@chromium.org Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 39 --- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 7489343..543ea2e0 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -211,7 +211,7 @@ struct sysmmu_drvdata { struct clk *clk; struct clk *clk_master; int activations; - rwlock_t lock; + spinlock_t lock; struct iommu_domain *domain; bool runtime_active; bool suspended; @@ -334,11 +334,12 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) unsigned long addr = -1; int ret = -ENOSYS; - read_lock(data-lock); - WARN_ON(!is_sysmmu_active(data)); + spin_lock(data-lock); + __master_clk_enable(data); + itype = (enum exynos_sysmmu_inttype) __ffs(__raw_readl(data-sfrbase + REG_INT_STATUS)); if (WARN_ON(!((itype = 0) (itype SYSMMU_FAULT_UNKNOWN @@ -371,7 +372,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) __master_clk_disable(data); - read_unlock(data-lock); + spin_unlock(data-lock); return IRQ_HANDLED; } @@ -392,7 +393,7 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data) bool disabled; unsigned long flags; - write_lock_irqsave(data-lock, flags); + spin_lock_irqsave(data-lock, flags); disabled = set_sysmmu_inactive(data); @@ -409,7 +410,7 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data) data-activations); } - write_unlock_irqrestore(data-lock, flags); + spin_unlock_irqrestore(data-lock, flags); return disabled; } @@ -457,7 +458,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data, int ret = 0; unsigned long flags; - write_lock_irqsave(data-lock, flags); + spin_lock_irqsave(data-lock, flags); if (set_sysmmu_active(data)) { data-pgtable = pgtable; data-domain = domain; @@ -475,7 +476,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data, if (WARN_ON(ret 0)) set_sysmmu_inactive(data); /* decrement count */ - write_unlock_irqrestore(data-lock, flags); + spin_unlock_irqrestore(data-lock, flags); return ret; } @@ -562,7 +563,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, for_each_sysmmu_list(dev, list) { struct sysmmu_drvdata *data = dev_get_drvdata(list-sysmmu); - read_lock(data-lock); + spin_lock(data-lock); if (is_sysmmu_active(data) data-runtime_active) { unsigned int num_inv = 1; @@ -594,7 +595,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova, iova); } - read_unlock(data-lock); + spin_unlock(data-lock); } spin_unlock_irqrestore(owner-lock, flags); @@ -610,7 +611,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev) for_each_sysmmu_list(dev, list) { struct sysmmu_drvdata *data = dev_get_drvdata(list-sysmmu); - read_lock(data-lock); + spin_lock(data-lock); if (is_sysmmu_active(data) data-runtime_active) { __master_clk_enable(data); if (sysmmu_block(data-sfrbase)) { @@ -621,7 +622,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev) } else { dev_dbg(dev, disabled. Skipping TLB invalidation\n); } - read_unlock(data-lock); + spin_unlock(data-lock); } spin_unlock_irqrestore(owner-lock, flags); @@ -819,7 +820,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev) if (!ret) { data-runtime_active = !pm_runtime_enabled(dev); data-sysmmu = dev; - rwlock_init(data-lock); + spin_lock_init(data-lock); platform_set_drvdata(pdev, data); } @@ -1269,12 +1270,12 @@ static int sysmmu_pm_genpd_suspend(struct device *dev) for_each_sysmmu_list(dev, list) { struct sysmmu_drvdata *data = dev_get_drvdata(list-sysmmu); unsigned long flags; - write_lock_irqsave(data-lock, flags); + spin_lock_irqsave(data-lock, flags); if (!data-suspended is_sysmmu_active(data) (!pm_runtime_enabled(dev) ||
[PATCH v11 22/27] iommu/exynos: add devices attached to the System MMU to an IOMMU group
Patch written by Antonios Motakis a.mota...@virtualopensystems.com: IOMMU groups are expected by certain users of the IOMMU API, e.g. VFIO. Since each device is behind its own System MMU, we can allocate a new IOMMU group for each device. Reviewd-by: Cho KyongHo pullip@samsung.com Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com --- drivers/iommu/exynos-iommu.c | 28 1 file changed, 28 insertions(+) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 543ea2e0..2beb197 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -1213,6 +1213,32 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain, return phys; } +static int exynos_iommu_add_device(struct device *dev) +{ + struct iommu_group *group; + int ret; + + group = iommu_group_get(dev); + + if (!group) { + group = iommu_group_alloc(); + if (IS_ERR(group)) { + dev_err(dev, Failed to allocate IOMMU group\n); + return PTR_ERR(group); + } + } + + ret = iommu_group_add_device(group, dev); + iommu_group_put(group); + + return ret; +} + +static void exynos_iommu_remove_device(struct device *dev) +{ + iommu_group_remove_device(dev); +} + static struct iommu_ops exynos_iommu_ops = { .domain_init = exynos_iommu_domain_init, .domain_destroy = exynos_iommu_domain_destroy, @@ -1221,6 +1247,8 @@ static struct iommu_ops exynos_iommu_ops = { .map = exynos_iommu_map, .unmap = exynos_iommu_unmap, .iova_to_phys = exynos_iommu_iova_to_phys, + .add_device = exynos_iommu_add_device, + .remove_device = exynos_iommu_remove_device, .pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE, }; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 23/27] iommu/exynos: fix address handling
Use of __pa and __va macro is changed to virt_to_phys and phys_to_virt which are recommended in driver code. printk formatting of physical address is also fixed to %pa. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 45 +++--- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 2beb197..e375501 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -142,7 +142,8 @@ static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova) static unsigned long *page_entry(unsigned long *sent, unsigned long iova) { - return (unsigned long *)__va(lv2table_base(sent)) + lv2ent_offset(iova); + return (unsigned long *)phys_to_virt( + lv2table_base(sent)) + lv2ent_offset(iova); } enum exynos_sysmmu_inttype { @@ -215,7 +216,7 @@ struct sysmmu_drvdata { struct iommu_domain *domain; bool runtime_active; bool suspended; - unsigned long pgtable; + phys_addr_t pgtable; }; static bool set_sysmmu_active(struct sysmmu_drvdata *data) @@ -307,17 +308,17 @@ static void __sysmmu_set_ptbase(void __iomem *sfrbase, static void show_fault_information(const char *name, enum exynos_sysmmu_inttype itype, - unsigned long pgtable_base, unsigned long fault_addr) + phys_addr_t pgtable_base, unsigned long fault_addr) { unsigned long *ent; if ((itype = SYSMMU_FAULTS_NUM) || (itype SYSMMU_PAGEFAULT)) itype = SYSMMU_FAULT_UNKNOWN; - pr_err(%s occurred at 0x%lx by %s(Page table base: 0x%lx)\n, - sysmmu_fault_name[itype], fault_addr, name, pgtable_base); + pr_err(%s occurred at %#lx by %s(Page table base: %pa)\n, + sysmmu_fault_name[itype], fault_addr, name, pgtable_base); - ent = section_entry(__va(pgtable_base), fault_addr); + ent = section_entry(phys_to_virt(pgtable_base), fault_addr); pr_err(\tLv1 entry: 0x%lx\n, *ent); if (lv1ent_page(ent)) { @@ -917,7 +918,7 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain) for (i = 0; i NUM_LV1ENTRIES; i++) if (lv1ent_page(priv-pgtable + i)) kmem_cache_free(lv2table_kmem_cache, - __va(lv2table_base(priv-pgtable + i))); + phys_to_virt(lv2table_base(priv-pgtable + i))); free_pages((unsigned long)priv-pgtable, 2); free_pages((unsigned long)priv-lv2entcnt, 1); @@ -931,11 +932,12 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain, struct exynos_iommu_owner *owner = dev-archdata.iommu; struct exynos_iommu_domain *priv = domain-priv; unsigned long flags; + phys_addr_t pgtable = virt_to_phys(priv-pgtable); int ret; spin_lock_irqsave(priv-lock, flags); - ret = __exynos_sysmmu_enable(dev, __pa(priv-pgtable), domain); + ret = __exynos_sysmmu_enable(dev, pgtable, domain); if (ret == 0) { list_add_tail(owner-client, priv-clients); owner-domain = domain; @@ -943,13 +945,14 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain, spin_unlock_irqrestore(priv-lock, flags); - if (ret 0) - dev_err(dev, %s: Failed to attach IOMMU with pgtable %#x\n, - __func__, __pa(priv-pgtable)); - else - dev_dbg(dev, %s: Attached IOMMU with pgtable 0x%x%s\n, - __func__, __pa(priv-pgtable), - (ret == 0) ? : , again); + if (ret 0) { + dev_err(dev, %s: Failed to attach IOMMU with pgtable %pa\n, + __func__, pgtable); + return ret; + } + + dev_dbg(dev, %s: Attached IOMMU with pgtable %pa %s\n, + __func__, pgtable, (ret == 0) ? : , again); return ret; } @@ -975,11 +978,13 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain, spin_unlock_irqrestore(priv-lock, flags); - if (owner == dev-archdata.iommu) - dev_dbg(dev, %s: Detached IOMMU with pgtable %#x\n, - __func__, __pa(priv-pgtable)); - else + if (owner == dev-archdata.iommu) { + phys_addr_t pgtable = virt_to_phys(priv-pgtable); + dev_dbg(dev, %s: Detached IOMMU with pgtable %pa\n, + __func__, pgtable); + } else { dev_dbg(dev, %s: No IOMMU is attached\n, __func__); + } } static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova, @@ -998,7 +1003,7 @@ static unsigned long *alloc_lv2entry(unsigned long *sent,
[PATCH v11 24/27] iommu/exynos: use exynos-iommu specific typedef
This commit introduces sysmmu_pte_t for page table entries and sysmmu_iova_t vor I/O virtual address that is manipulated by exynos-iommu driver. The purpose of the typedef is to remove dependencies to the driver code from the change of CPU architecture from 32 bit to 64 bit. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 103 ++ 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index e375501..6e716cc 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -56,19 +56,19 @@ #define lv2ent_large(pent) ((*(pent) 3) == 1) #define section_phys(sent) (*(sent) SECT_MASK) -#define section_offs(iova) ((iova) 0xF) +#define section_offs(iova) ((sysmmu_iova_t)(iova) 0xF) #define lpage_phys(pent) (*(pent) LPAGE_MASK) -#define lpage_offs(iova) ((iova) 0x) +#define lpage_offs(iova) ((sysmmu_iova_t)(iova) 0x) #define spage_phys(pent) (*(pent) SPAGE_MASK) -#define spage_offs(iova) ((iova) 0xFFF) +#define spage_offs(iova) ((sysmmu_iova_t)(iova) 0xFFF) -#define lv1ent_offset(iova) ((iova) SECT_ORDER) -#define lv2ent_offset(iova) (((iova) 0xFF000) SPAGE_ORDER) +#define lv1ent_offset(iova) ((sysmmu_iova_t)(iova) SECT_ORDER) +#define lv2ent_offset(iova) (((sysmmu_iova_t)(iova) 0xFF000) SPAGE_ORDER) #define NUM_LV1ENTRIES 4096 -#define NUM_LV2ENTRIES 256 +#define NUM_LV2ENTRIES (SECT_SIZE / SPAGE_SIZE) -#define LV2TABLE_SIZE (NUM_LV2ENTRIES * sizeof(long)) +#define LV2TABLE_SIZE (NUM_LV2ENTRIES * sizeof(sysmmu_pte_t)) #define SPAGES_PER_LPAGE (LPAGE_SIZE / SPAGE_SIZE) @@ -133,16 +133,19 @@ ((struct exynos_iommu_owner *)dev-archdata.iommu)-mmu_list, \ entry) +typedef u32 sysmmu_iova_t; +typedef u32 sysmmu_pte_t; + static struct kmem_cache *lv2table_kmem_cache; -static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova) +static sysmmu_pte_t *section_entry(sysmmu_pte_t *pgtable, sysmmu_iova_t iova) { return pgtable + lv1ent_offset(iova); } -static unsigned long *page_entry(unsigned long *sent, unsigned long iova) +static sysmmu_pte_t *page_entry(sysmmu_pte_t *sent, sysmmu_iova_t iova) { - return (unsigned long *)phys_to_virt( + return (sysmmu_pte_t *)phys_to_virt( lv2table_base(sent)) + lv2ent_offset(iova); } @@ -194,7 +197,7 @@ struct exynos_iommu_owner { struct exynos_iommu_domain { struct list_head clients; /* list of sysmmu_drvdata.node */ - unsigned long *pgtable; /* lv1 page table, 16KB */ + sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */ short *lv2entcnt; /* free lv2 entry counter for each section */ spinlock_t lock; /* lock for this structure */ spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */ @@ -288,7 +291,7 @@ static void __sysmmu_tlb_invalidate(void __iomem *sfrbase) } static void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase, - unsigned long iova, unsigned int num_inv) + sysmmu_iova_t iova, unsigned int num_inv) { unsigned int i; for (i = 0; i num_inv; i++) { @@ -299,7 +302,7 @@ static void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase, } static void __sysmmu_set_ptbase(void __iomem *sfrbase, - unsigned long pgd) + phys_addr_t pgd) { __raw_writel(pgd, sfrbase + REG_PT_BASE_ADDR); @@ -308,22 +311,22 @@ static void __sysmmu_set_ptbase(void __iomem *sfrbase, static void show_fault_information(const char *name, enum exynos_sysmmu_inttype itype, - phys_addr_t pgtable_base, unsigned long fault_addr) + phys_addr_t pgtable_base, sysmmu_iova_t fault_addr) { - unsigned long *ent; + sysmmu_pte_t *ent; if ((itype = SYSMMU_FAULTS_NUM) || (itype SYSMMU_PAGEFAULT)) itype = SYSMMU_FAULT_UNKNOWN; - pr_err(%s occurred at %#lx by %s(Page table base: %pa)\n, + pr_err(%s occurred at %#x by %s(Page table base: %pa)\n, sysmmu_fault_name[itype], fault_addr, name, pgtable_base); ent = section_entry(phys_to_virt(pgtable_base), fault_addr); - pr_err(\tLv1 entry: 0x%lx\n, *ent); + pr_err(\tLv1 entry: %#x\n, *ent); if (lv1ent_page(ent)) { ent = page_entry(ent, fault_addr); - pr_err(\t Lv2 entry: 0x%lx\n, *ent); + pr_err(\t Lv2 entry: %#x\n, *ent); } } @@ -332,7 +335,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) /* SYSMMU is in blocked when interrupt occurred. */ struct sysmmu_drvdata *data = dev_id; enum exynos_sysmmu_inttype itype; - unsigned long addr = -1; + sysmmu_iova_t addr = -1; int ret =
[PATCH v11 26/27] iommu/exynos: apply workaround of caching fault page table entries
This patch contains 2 workaround for the System MMU v3.x. System MMU v3.2 and v3.3 has FLPD cache that caches first level page table entries to reduce page table walking latency. However, the FLPD cache is filled with a first level page table entry even though it is not accessed by a master H/W because System MMU v3.3 speculatively prefetches page table entries that may be accessed in the near future by the master H/W. The prefetched FLPD cache entries are not invalidated by iommu_unmap() because iommu_unmap() only unmaps and invalidates the page table entries that is mapped. Because exynos-iommu driver discards a second level page table when it needs to be replaced with another second level page table or a first level page table entry with 1MB mapping, It is required to invalidate FLPD cache that may contain the first level page table entry that points to the second level page table. Another workaround of System MMU v3.3 is initializing the first level page table entries with the second level page table which is filled with all zeros. This prevents System MMU prefetches 'fault' first level page table entry which may lead page fault on access to 16MiB wide. System MMU 3.x fetches consecutive page table entries by a page table walking to maximize bus utilization and to minimize TLB miss panelty. Unfortunately, functional problem is raised with the fetching behavior because it fetches 'fault' page table entries that specifies no translation information and that a valid translation information will be written to in the near future. The logic in the System MMU generates page fault with the cached fault entries that is no longer coherent with the page table which is updated. There is another workaround that must be implemented by I/O virtual memory manager: any two consecutive I/O virtual memory area must have a hole between the two that is larger than or equal to 128KiB. Also, next I/O virtual memory area must be started from the next 128KiB boundary. 0128K 256K 384K 512K |-|---|-|| |area1|.hole...|--- area2 - The constraint is depicted above. The size is selected by the calculation followed: - System MMU can fetch consecutive 64 page table entries at once 64 * 4KiB = 256KiB. This is the size between 128K ~ 384K of the above picture. This style of fetching is 'block fetch'. It fetches the page table entries predefined consecutive page table entries including the entry that is the reason of the page table walking. - System MMU can prefetch upto consecutive 32 page table entries. This is the size between 256K ~ 384K. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 164 +- 1 file changed, 147 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 3d4dabb..4888383 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -47,8 +47,12 @@ #define LPAGE_MASK (~(LPAGE_SIZE - 1)) #define SPAGE_MASK (~(SPAGE_SIZE - 1)) -#define lv1ent_fault(sent) (((*(sent) 3) == 0) || ((*(sent) 3) == 3)) -#define lv1ent_page(sent) ((*(sent) 3) == 1) +#define lv1ent_fault(sent) ((*(sent) == ZERO_LV2LINK) || \ + ((*(sent) 3) == 0) || ((*(sent) 3) == 3)) +#define lv1ent_zero(sent) (*(sent) == ZERO_LV2LINK) +#define lv1ent_page_zero(sent) ((*(sent) 3) == 1) +#define lv1ent_page(sent) ((*(sent) != ZERO_LV2LINK) \ + ((*(sent) 3) == 1)) #define lv1ent_section(sent) ((*(sent) 3) == 2) #define lv2ent_fault(pent) ((*(pent) 3) == 0) @@ -137,6 +141,8 @@ typedef u32 sysmmu_iova_t; typedef u32 sysmmu_pte_t; static struct kmem_cache *lv2table_kmem_cache; +static sysmmu_pte_t *zero_lv2_table; +#define ZERO_LV2LINK mk_lv1ent_page(virt_to_phys(zero_lv2_table)) static sysmmu_pte_t *section_entry(sysmmu_pte_t *pgtable, sysmmu_iova_t iova) { @@ -538,6 +544,33 @@ static bool exynos_sysmmu_disable(struct device *dev) return disabled; } +static void __sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data, + sysmmu_iova_t iova) +{ + if (__raw_sysmmu_version(data) == MAKE_MMU_VER(3, 3)) + __raw_writel(iova | 0x1, data-sfrbase + REG_MMU_FLUSH_ENTRY); +} + +static void sysmmu_tlb_invalidate_flpdcache(struct device *dev, + sysmmu_iova_t iova) +{ + struct sysmmu_list_data *list; + + for_each_sysmmu_list(dev, list) { + unsigned long flags; + struct sysmmu_drvdata *data = dev_get_drvdata(list-sysmmu); + + __master_clk_enable(data); + + spin_lock_irqsave(data-lock, flags); + if (is_sysmmu_active(data) data-runtime_active) +
[PATCH v11 27/27] iommu/exynos: enhanced error messages
Some redundant error message is removed and some error messages are changed to error level from debug level. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 23 +-- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 4888383..b7f7731 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -1012,7 +1012,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain, dev_dbg(dev, %s: Detached IOMMU with pgtable %pa\n, __func__, pgtable); } else { - dev_dbg(dev, %s: No IOMMU is attached\n, __func__); + dev_err(dev, %s: No IOMMU is attached\n, __func__); } } @@ -1112,10 +1112,8 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size, short *pgcnt) { if (size == SPAGE_SIZE) { - if (!lv2ent_fault(pent)) { - WARN(1, Trying mapping on 4KiB where mapping exists); + if (WARN_ON(!lv2ent_fault(pent))) return -EADDRINUSE; - } *pent = mk_lv2ent_spage(paddr); pgtable_flush(pent, pent + 1); @@ -1123,9 +1121,7 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size, } else { /* size == LPAGE_SIZE */ int i; for (i = 0; i SPAGES_PER_LPAGE; i++, pent++) { - if (!lv2ent_fault(pent)) { - WARN(1, - Trying mapping on 64KiB where mapping exists); + if (WARN_ON(!lv2ent_fault(pent))) { if (i 0) memset(pent - i, 0, sizeof(*pent) * i); return -EADDRINUSE; @@ -1198,8 +1194,8 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova, } if (ret) - pr_debug(%s: Failed to map iova %#x/%#zx bytes\n, - __func__, iova, size); + pr_err(%s: Failed(%d) to map %#zx bytes @ %#x\n, + __func__, ret, size, iova); spin_unlock_irqrestore(priv-pgtablelock, flags); @@ -1236,7 +1232,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain, ent = section_entry(priv-pgtable, iova); if (lv1ent_section(ent)) { - if (size SECT_SIZE) { + if (WARN_ON(size SECT_SIZE)) { err_pgsize = SECT_SIZE; goto err; } @@ -1271,7 +1267,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain, } /* lv1ent_large(ent) == true here */ - if (size LPAGE_SIZE) { + if (WARN_ON(size LPAGE_SIZE)) { err_pgsize = LPAGE_SIZE; goto err; } @@ -1290,9 +1286,8 @@ done: err: spin_unlock_irqrestore(priv-pgtablelock, flags); - WARN(1, - %s: Failed due to size(%#zx) @ %#x is smaller than page size %#zx\n, - __func__, size, iova, err_pgsize); + pr_err(%s: Failed: size(%#zx) @ %#x is smaller than page size %#zx\n, + __func__, size, iova, err_pgsize); return 0; } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 25/27] iommu/exynos: use simpler function to get MMU version
This commit changes the function to get MMU version simpler. Signed-off-by: Cho KyongHo pullip@samsung.com --- drivers/iommu/exynos-iommu.c | 30 ++ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 6e716cc..3d4dabb 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -251,24 +251,6 @@ static unsigned int __raw_sysmmu_version(struct sysmmu_drvdata *data) return MMU_RAW_VER(__raw_readl(data-sfrbase + REG_MMU_VERSION)); } -static unsigned int __sysmmu_version(struct sysmmu_drvdata *data, -unsigned int *minor) -{ - unsigned int ver = 0; - - ver = __raw_sysmmu_version(data); - if (ver MAKE_MMU_VER(3, 3)) { - dev_err(data-sysmmu, %s: version(%d.%d) is higher than 3.3\n, - __func__, MMU_MAJ_VER(ver), MMU_MIN_VER(ver)); - BUG(); - } - - if (minor) - *minor = MMU_MIN_VER(ver); - - return MMU_MAJ_VER(ver); -} - static bool sysmmu_block(void __iomem *sfrbase) { int i = 120; @@ -422,13 +404,13 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data) static void __sysmmu_init_config(struct sysmmu_drvdata *data) { unsigned int cfg = CFG_LRU | CFG_QOS(15); - int maj, min = 0; + unsigned int ver; - maj = __sysmmu_version(data, min); - if (maj == 3) { - if (min = 2) { + ver = __raw_sysmmu_version(data); + if (MMU_MAJ_VER(ver) == 3) { + if (MMU_MIN_VER(ver) = 2) { cfg |= CFG_FLPDCACHE; - if (min == 3) { + if (MMU_MIN_VER(ver) == 3) { cfg |= CFG_ACGEN; cfg = ~CFG_LRU; } else { @@ -583,7 +565,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova, * 1MB page can be cached in one of all sets. * 64KB page can be one of 16 consecutive sets. */ - if (__sysmmu_version(data, NULL) == 2) + if (MMU_MAJ_VER(__raw_sysmmu_version(data)) == 2) num_inv = min_t(unsigned int, size / PAGE_SIZE, 64); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html