diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts index db2705afa4e222..6c16c325cd2887 100644 --- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts @@ -133,7 +133,6 @@ / { __overrides__ { uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; uart1 = <&uart1>,"status"; i2s = <&i2s>,"status"; spi = <&spi0>,"status"; @@ -143,7 +142,6 @@ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; i2c1_baudrate = <&i2c1>,"clock-frequency:0"; i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; act_led_gpio = <&act_led>,"gpios:4"; act_led_activelow = <&act_led>,"gpios:8"; diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts index beae0371477cc4..7c132437671d43 100644 --- a/arch/arm/boot/dts/bcm2708-rpi-b.dts +++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts @@ -127,7 +127,6 @@ / { __overrides__ { uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; uart1 = <&uart1>,"status"; i2s = <&i2s>,"status"; spi = <&spi0>,"status"; @@ -137,7 +136,6 @@ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; i2c1_baudrate = <&i2c1>,"clock-frequency:0"; i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; act_led_gpio = <&act_led>,"gpios:4"; act_led_activelow = <&act_led>,"gpios:8"; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts index cd0e1acc22f8de..d2dcc9c156b32a 100755 --- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts @@ -88,7 +88,6 @@ / { __overrides__ { uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; uart1 = <&uart1>,"status"; i2s = <&i2s>,"status"; spi = <&spi0>,"status"; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi index 90e330d1978da8..f07609d97225b3 100644 --- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi @@ -38,8 +38,6 @@ / { __overrides__ { - core_freq = <&clk_core>,"clock-frequency:0"; - act_led_gpio = <&act_led>,"gpios:4"; act_led_activelow = <&act_led>,"gpios:8"; act_led_trigger = <&act_led>,"linux,default-trigger"; diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi index 74434b986e3fbb..7df436bea6cbdc 100644 --- a/arch/arm/boot/dts/bcm2708_common.dtsi +++ b/arch/arm/boot/dts/bcm2708_common.dtsi @@ -113,7 +113,6 @@ * oscillator. */ clocks = <&clk_osc>; - status = "disabled"; }; random: rng@7e104000 { @@ -134,11 +133,12 @@ #interrupt-cells = <2>; }; - uart0: uart@7e201000 { - compatible = "arm,pl011", "arm,primecell"; + uart0: serial@7e201000 { + compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; reg = <0x7e201000 0x1000>; interrupts = <2 25>; - clocks = <&clk_uart0 &clk_apb_p>; + clocks = <&cprman BCM2835_CLOCK_UART>, + <&cprman BCM2835_CLOCK_VPU>; clock-names = "uartclk","apb_pclk"; arm,primecell-periphid = <0x00241011>; // For an explanation, see // https://github.com/raspberrypi/linux/commit/13731d862cf5219216533a3b0de052cee4cc5038 @@ -149,7 +149,7 @@ compatible = "brcm,bcm2835-sdhost"; reg = <0x7e202000 0x100>; interrupts = <2 24>; - clocks = <&clk_core>; + clocks = <&cprman BCM2835_CLOCK_VPU>; dmas = <&dma 13>; dma-names = "rx-tx"; brcm,overclock-50 = <0>; @@ -160,8 +160,8 @@ i2s: i2s@7e203000 { compatible = "brcm,bcm2835-i2s"; #sound-dai-cells = <0>; - reg = <0x7e203000 0x24>, - <0x7e101098 0x08>; + reg = <0x7e203000 0x24>; + clocks = <&cprman BCM2835_CLOCK_PCM>; dmas = <&dma 2>, <&dma 3>; dma-names = "tx", "rx"; @@ -172,7 +172,7 @@ compatible = "brcm,bcm2835-spi"; reg = <0x7e204000 0x1000>; interrupts = <2 22>; - clocks = <&clk_core>; + clocks = <&cprman BCM2835_CLOCK_VPU>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -190,7 +190,7 @@ compatible = "brcm,bcm2708-i2c"; reg = <0x7e205000 0x1000>; interrupts = <2 21>; - clocks = <&clk_core>; + clocks = <&cprman BCM2835_CLOCK_VPU>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -222,32 +222,31 @@ pwm: pwm@7e20c000 { compatible = "brcm,bcm2835-pwm"; reg = <0x7e20c000 0x28>; - clocks = <&clk_pwm>; + clocks = <&cprman BCM2835_CLOCK_PWM>; + assigned-clocks = <&cprman BCM2835_CLOCK_PWM>; + assigned-clock-rates = <10000000>; #pwm-cells = <2>; status = "disabled"; }; - aux: aux@0x7e215004 { + aux: aux@0x7e215000 { compatible = "brcm,bcm2835-aux"; #clock-cells = <1>; reg = <0x7e215000 0x8>; - clocks = <&clk_core>; - status = "disabled"; + clocks = <&cprman BCM2835_CLOCK_VPU>; }; - uart1: uart@7e215040 { - compatible = "brcm,bcm2835-aux-uart", "ns16550"; + uart1: serial@7e215040 { + compatible = "brcm,bcm2835-aux-uart"; reg = <0x7e215040 0x40>; interrupts = <1 29>; - clocks = <&clk_uart1>; - reg-shift = <2>; - no-loopback-test; + clocks = <&aux BCM2835_AUX_CLOCK_UART>; status = "disabled"; }; spi1: spi@7e215080 { compatible = "brcm,bcm2835-aux-spi"; - reg = <0x7e215080 0x40>, <0x7e215000 0x8>; + reg = <0x7e215080 0x40>; interrupts = <1 29>; clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; #address-cells = <1>; @@ -257,7 +256,7 @@ spi2: spi@7e2150C0 { compatible = "brcm,bcm2835-aux-spi"; - reg = <0x7e2150C0 0x40>, <0x7e215000 0x8>; + reg = <0x7e2150C0 0x40>; interrupts = <1 29>; clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; #address-cells = <1>; @@ -269,7 +268,7 @@ compatible = "brcm,bcm2835-mmc"; reg = <0x7e300000 0x100>; interrupts = <2 30>; - clocks = <&clk_mmc>; + clocks = <&cprman BCM2835_CLOCK_EMMC>; dmas = <&dma 11>; dma-names = "rx-tx"; brcm,overclock-50 = <0>; @@ -286,7 +285,7 @@ compatible = "brcm,bcm2708-i2c"; reg = <0x7e804000 0x1000>; interrupts = <2 21>; - clocks = <&clk_core>; + clocks = <&cprman BCM2835_CLOCK_VPU>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -299,7 +298,7 @@ compatible = "brcm,bcm2708-i2c"; reg = <0x7e805000 0x1000>; interrupts = <2 21>; - clocks = <&clk_core>; + clocks = <&cprman BCM2835_CLOCK_VPU>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -307,10 +306,11 @@ smi: smi@7e600000 { compatible = "brcm,bcm2835-smi"; - reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>; + reg = <0x7e600000 0x100>; interrupts = <2 16>; - brcm,smi-clock-source = <6>; - brcm,smi-clock-divisor = <4>; + clocks = <&cprman BCM2835_CLOCK_SMI>; + assigned-clocks = <&cprman BCM2835_CLOCK_SMI>; + assigned-clock-rates = <125000000>; dmas = <&dma 4>; dma-names = "rx-tx"; status = "disabled"; @@ -406,55 +406,6 @@ #address-cells = <1>; #size-cells = <0>; - clk_core: clock@0 { - compatible = "fixed-clock"; - reg = <0>; - #clock-cells = <0>; - clock-output-names = "core"; - clock-frequency = <250000000>; - }; - - clk_mmc: clock@1 { - compatible = "fixed-clock"; - reg = <1>; - #clock-cells = <0>; - clock-output-names = "mmc"; - clock-frequency = <250000000>; - }; - - clk_uart0: clock@2 { - compatible = "fixed-clock"; - reg = <2>; - #clock-cells = <0>; - clock-output-names = "uart0_pclk"; - clock-frequency = <3000000>; - }; - - clk_apb_p: clock@3 { - compatible = "fixed-clock"; - reg = <3>; - #clock-cells = <0>; - clock-output-names = "apb_pclk"; - clock-frequency = <126000000>; - }; - - clk_pwm: clock@4 { - compatible = "fixed-clock"; - reg = <4>; - #clock-cells = <0>; - clock-output-names = "pwm"; - clock-frequency = <100000000>; - }; - - clk_uart1: clock@5 { - compatible = "fixed-factor-clock"; - reg = <5>; - clocks = <&clk_core>; - #clock-cells = <0>; - clock-div = <1>; - clock-mult = <2>; - }; - /* The oscillator is the root of the clock tree. */ clk_osc: clock@6 { compatible = "fixed-clock"; diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts index eca72bd0d6e891..74fe4cc1d667e9 100644 --- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts @@ -133,7 +133,6 @@ / { __overrides__ { uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; uart1 = <&uart1>,"status"; i2s = <&i2s>,"status"; spi = <&spi0>,"status"; @@ -143,7 +142,6 @@ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; i2c1_baudrate = <&i2c1>,"clock-frequency:0"; i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; act_led_gpio = <&act_led>,"gpios:4"; act_led_activelow = <&act_led>,"gpios:8"; diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts index a72e6e5a0ac0b2..037ed41b140c44 100644 --- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts @@ -184,7 +184,6 @@ / { __overrides__ { uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; uart1 = <&uart1>,"status"; i2s = <&i2s>,"status"; spi = <&spi0>,"status"; @@ -194,7 +193,6 @@ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; i2c1_baudrate = <&i2c1>,"clock-frequency:0"; i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; act_led_gpio = <&act_led>,"gpios:4"; act_led_activelow = <&act_led>,"gpios:8"; diff --git a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts index 6a3d2f21295a63..a5d57893d5799e 100644 --- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts @@ -149,7 +149,6 @@ / { __overrides__ { uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; uart1 = <&uart1>,"status"; i2s = <&i2s>,"status"; spi = <&spi0>,"status"; @@ -159,7 +158,6 @@ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; i2c1_baudrate = <&i2c1>,"clock-frequency:0"; i2c2_baudrate = <&i2c2>,"clock-frequency:0"; - core_freq = <&clk_core>,"clock-frequency:0"; act_led_gpio = <&act_led>,"gpios:4"; act_led_activelow = <&act_led>,"gpios:8"; diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile index d4f31b76931d69..68832129f46b9c 100644 --- a/arch/arm/boot/dts/overlays/Makefile +++ b/arch/arm/boot/dts/overlays/Makefile @@ -41,7 +41,6 @@ dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo dtbo-$(RPI_DT_OVERLAYS) += i2s-gpio28-31.dtbo -dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dac.dtbo dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dacplus.dtbo dtbo-$(RPI_DT_OVERLAYS) += iqaudio-digi-wm8804-audio.dtbo diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 57100ecd457217..b32bca8ada3b10 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -510,12 +510,6 @@ Load: dtoverlay=i2s-gpio28-31 Params: -Name: i2s-mmap -Info: Enables mmap support in the bcm2708-i2s driver -Load: dtoverlay=i2s-mmap -Params: - - Name: iqaudio-dac Info: Configures the IQaudio DAC audio card Load: dtoverlay=iqaudio-dac, diff --git a/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts b/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts deleted file mode 100644 index a11160afa4bfb2..00000000000000 --- a/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts +++ /dev/null @@ -1,13 +0,0 @@ -/dts-v1/; -/plugin/; - -/{ - compatible = "brcm,bcm2708"; - - fragment@0 { - target = <&i2s>; - __overlay__ { - brcm,enable-mmap; - }; - }; -}; diff --git a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts index 68f6069dd24cbf..87cf345f9641e6 100644 --- a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts +++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts @@ -39,8 +39,8 @@ fragment@3 { target-path = "/aliases"; __overlay__ { - serial0 = "/soc/uart@7e201000"; - serial1 = "/soc/uart@7e215040"; + serial0 = "/soc/serial@7e201000"; + serial1 = "/soc/serial@7e215040"; }; }; }; diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts index 17d04cf87195a6..18f77453c38dbb 100644 --- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts +++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts @@ -57,8 +57,8 @@ fragment@4 { target-path = "/aliases"; __overlay__ { - serial0 = "/soc/uart@7e201000"; - serial1 = "/soc/uart@7e215040"; + serial0 = "/soc/serial@7e201000"; + serial1 = "/soc/serial@7e215040"; }; }; }; diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig index e85cf56113b432..76340ce6ccc43a 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig @@ -595,6 +595,9 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_DMA is not set CONFIG_SERIAL_8250_NR_UARTS=1 CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig index 4b50842b84daf9..5535fee75c1a31 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig @@ -587,6 +587,9 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_DMA is not set CONFIG_SERIAL_8250_NR_UARTS=1 CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y diff --git a/drivers/misc/bcm2835_smi.c b/drivers/misc/bcm2835_smi.c index 63a4ea08b9930a..1261540703127d 100644 --- a/drivers/misc/bcm2835_smi.c +++ b/drivers/misc/bcm2835_smi.c @@ -34,6 +34,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -62,7 +63,7 @@ struct bcm2835_smi_instance { struct device *dev; struct smi_settings settings; - __iomem void *smi_regs_ptr, *cm_smi_regs_ptr; + __iomem void *smi_regs_ptr; dma_addr_t smi_regs_busaddr; struct dma_chan *dma_chan; @@ -72,50 +73,13 @@ struct bcm2835_smi_instance { struct scatterlist buffer_sgl; - int clock_source; - int clock_divisor; + struct clk *clk; /* Sometimes we are called into in an atomic context (e.g. by JFFS2 + MTD) so we can't use a mutex */ spinlock_t transaction_lock; }; -/**************************************************************************** -* -* SMI clock manager setup -* -***************************************************************************/ - -static inline void write_smi_cm_reg(struct bcm2835_smi_instance *inst, - u32 val, unsigned reg) -{ - writel(CM_PWD | val, inst->cm_smi_regs_ptr + reg); -} - -static inline u32 read_smi_cm_reg(struct bcm2835_smi_instance *inst, - unsigned reg) -{ - return readl(inst->cm_smi_regs_ptr + reg); -} - -static void smi_setup_clock(struct bcm2835_smi_instance *inst) -{ - dev_dbg(inst->dev, "Setting up clock..."); - /* Disable SMI clock and wait for it to stop. */ - write_smi_cm_reg(inst, 0, CM_SMI_CTL); - while (read_smi_cm_reg(inst, CM_SMI_CTL) & CM_SMI_CTL_BUSY) - ; - - write_smi_cm_reg(inst, (inst->clock_divisor << CM_SMI_DIV_DIVI_OFFS), - CM_SMI_DIV); - write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS), - CM_SMI_CTL); - - /* Enable the clock */ - write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS) | - CM_SMI_CTL_ENAB, CM_SMI_CTL); -} - /**************************************************************************** * * SMI peripheral setup @@ -894,42 +858,40 @@ static int bcm2835_smi_probe(struct platform_device *pdev) struct device_node *node = dev->of_node; struct resource *ioresource; struct bcm2835_smi_instance *inst; + const __be32 *addr; + /* We require device tree support */ + if (!node) + return -EINVAL; /* Allocate buffers and instance data */ - inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance), GFP_KERNEL); - if (!inst) return -ENOMEM; inst->dev = dev; spin_lock_init(&inst->transaction_lock); - /* We require device tree support */ - if (!node) - return -EINVAL; - ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource); - ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 1); - inst->cm_smi_regs_ptr = devm_ioremap_resource(dev, ioresource); - inst->smi_regs_busaddr = be32_to_cpu( - *of_get_address(node, 0, NULL, NULL)); - of_property_read_u32(node, - "brcm,smi-clock-source", - &inst->clock_source); - of_property_read_u32(node, - "brcm,smi-clock-divisor", - &inst->clock_divisor); + if (IS_ERR(inst->smi_regs_ptr)) { + err = PTR_ERR(inst->smi_regs_ptr); + goto err; + } + addr = of_get_address(node, 0, NULL, NULL); + inst->smi_regs_busaddr = be32_to_cpu(addr); err = bcm2835_smi_dma_setup(inst); if (err) - return err; + goto err; - /* Finally, do peripheral setup */ + /* request clock */ + inst->clk = devm_clk_get(dev, NULL); + if (!inst->clk) + goto err; + clk_prepare_enable(inst->clk); - smi_setup_clock(inst); + /* Finally, do peripheral setup */ smi_setup_regs(inst); platform_set_drvdata(pdev, inst); @@ -937,6 +899,9 @@ static int bcm2835_smi_probe(struct platform_device *pdev) dev_info(inst->dev, "initialised"); return 0; +err: + kfree(inst); + return err; } /**************************************************************************** @@ -950,6 +915,11 @@ static int bcm2835_smi_remove(struct platform_device *pdev) struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev); struct device *dev = inst->dev; + dmaengine_terminate_all(inst->dma_chan); + dma_release_channel(inst->dma_chan); + + clk_disable_unprepare(inst->clk); + dev_info(dev, "SMI device removed - OK"); return 0; } diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index e46761d20f7b4c..1232132f218b5c 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -291,7 +291,7 @@ config SERIAL_8250_ACORN config SERIAL_8250_BCM2835AUX tristate "BCM2835 auxiliar mini UART support" - depends on ARCH_BCM2835 || COMPILE_TEST + depends on ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835 || COMPILE_TEST depends on SERIAL_8250 && SERIAL_8250_SHARE_IRQ help Support for the BCM2835 auxiliar mini UART. diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index b26f9587dec01d..6ba20498202ed3 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -37,8 +37,8 @@ #include #include #include -#include #include +#include #include #include @@ -47,55 +47,6 @@ #include #include -/* Clock registers */ -#define BCM2835_CLK_PCMCTL_REG 0x00 -#define BCM2835_CLK_PCMDIV_REG 0x04 - -/* Clock register settings */ -#define BCM2835_CLK_PASSWD (0x5a000000) -#define BCM2835_CLK_PASSWD_MASK (0xff000000) -#define BCM2835_CLK_MASH(v) ((v) << 9) -#define BCM2835_CLK_FLIP BIT(8) -#define BCM2835_CLK_BUSY BIT(7) -#define BCM2835_CLK_KILL BIT(5) -#define BCM2835_CLK_ENAB BIT(4) -#define BCM2835_CLK_SRC(v) (v) - -#define BCM2835_CLK_SHIFT (12) -#define BCM2835_CLK_DIVI(v) ((v) << BCM2835_CLK_SHIFT) -#define BCM2835_CLK_DIVF(v) (v) -#define BCM2835_CLK_DIVF_MASK (0xFFF) - -enum { - BCM2835_CLK_MASH_0 = 0, - BCM2835_CLK_MASH_1, - BCM2835_CLK_MASH_2, - BCM2835_CLK_MASH_3, -}; - -enum { - BCM2835_CLK_SRC_GND = 0, - BCM2835_CLK_SRC_OSC, - BCM2835_CLK_SRC_DBG0, - BCM2835_CLK_SRC_DBG1, - BCM2835_CLK_SRC_PLLA, - BCM2835_CLK_SRC_PLLC, - BCM2835_CLK_SRC_PLLD, - BCM2835_CLK_SRC_HDMI, -}; - -/* Most clocks are not useable (freq = 0) */ -static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = { - [BCM2835_CLK_SRC_GND] = 0, - [BCM2835_CLK_SRC_OSC] = 19200000, - [BCM2835_CLK_SRC_DBG0] = 0, - [BCM2835_CLK_SRC_DBG1] = 0, - [BCM2835_CLK_SRC_PLLA] = 0, - [BCM2835_CLK_SRC_PLLC] = 0, - [BCM2835_CLK_SRC_PLLD] = 500000000, - [BCM2835_CLK_SRC_HDMI] = 0, -}; - /* I2S registers */ #define BCM2835_I2S_CS_A_REG 0x00 #define BCM2835_I2S_FIFO_A_REG 0x04 @@ -166,21 +117,23 @@ struct bcm2835_i2s_dev { unsigned int fmt; unsigned int bclk_ratio; - struct regmap *i2s_regmap; - struct regmap *clk_regmap; + struct regmap *i2s_regmap; + struct clk *clk; + bool clk_prepared; }; static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) { - /* Start the clock if in master mode */ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; + if (dev->clk_prepared) + return; + switch (master) { case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFM: - regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, - BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB, - BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB); + clk_prepare_enable(dev->clk); + dev->clk_prepared = true; break; default: break; @@ -189,28 +142,9 @@ static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev) { - uint32_t clkreg; - int timeout = 1000; - - /* Stop clock */ - regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, - BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB, - BCM2835_CLK_PASSWD); - - /* Wait for the BUSY flag going down */ - while (--timeout) { - regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg); - if (!(clkreg & BCM2835_CLK_BUSY)) - break; - } - - if (!timeout) { - /* KILL the clock */ - dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n"); - regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, - BCM2835_CLK_KILL | BCM2835_CLK_PASSWD_MASK, - BCM2835_CLK_KILL | BCM2835_CLK_PASSWD); - } + if (dev->clk_prepared) + clk_disable_unprepare(dev->clk); + dev->clk_prepared = false; } static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, @@ -220,8 +154,7 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, uint32_t syncval; uint32_t csreg; uint32_t i2s_active_state; - uint32_t clkreg; - uint32_t clk_active_state; + bool clk_was_prepared; uint32_t off; uint32_t clr; @@ -235,15 +168,10 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON); - regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg); - clk_active_state = clkreg & BCM2835_CLK_ENAB; - /* Start clock if not running */ - if (!clk_active_state) { - regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, - BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB, - BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB); - } + clk_was_prepared = dev->clk_prepared; + if (!clk_was_prepared) + bcm2835_i2s_start_clock(dev); /* Stop I2S module */ regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0); @@ -277,7 +205,7 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, dev_err(dev->dev, "I2S SYNC error!\n"); /* Stop clock if it was not running before */ - if (!clk_active_state) + if (!clk_was_prepared) bcm2835_i2s_stop_clock(dev); /* Restore I2S state */ @@ -306,19 +234,9 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); - unsigned int sampling_rate = params_rate(params); unsigned int data_length, data_delay, bclk_ratio; unsigned int ch1pos, ch2pos, mode, format; - unsigned int mash = BCM2835_CLK_MASH_1; - unsigned int divi, divf, target_frequency; - int clk_src = -1; - unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; - bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS - || master == SND_SOC_DAIFMT_CBS_CFM); - - bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS - || master == SND_SOC_DAIFMT_CBM_CFS); uint32_t csreg; /* @@ -340,15 +258,12 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: data_length = 16; - bclk_ratio = 50; break; case SNDRV_PCM_FORMAT_S24_LE: data_length = 24; - bclk_ratio = 50; break; case SNDRV_PCM_FORMAT_S32_LE: data_length = 32; - bclk_ratio = 100; break; default: return -EINVAL; @@ -357,75 +272,15 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, /* If bclk_ratio already set, use that one. */ if (dev->bclk_ratio) bclk_ratio = dev->bclk_ratio; - - /* - * Clock Settings - * - * The target frequency of the bit clock is - * sampling rate * frame length - * - * Integer mode: - * Sampling rates that are multiples of 8000 kHz - * can be driven by the oscillator of 19.2 MHz - * with an integer divider as long as the frame length - * is an integer divider of 19200000/8000=2400 as set up above. - * This is no longer possible if the sampling rate - * is too high (e.g. 192 kHz), because the oscillator is too slow. - * - * MASH mode: - * For all other sampling rates, it is not possible to - * have an integer divider. Approximate the clock - * with the MASH module that induces a slight frequency - * variance. To minimize that it is best to have the fastest - * clock here. That is PLLD with 500 MHz. - */ - target_frequency = sampling_rate * bclk_ratio; - clk_src = BCM2835_CLK_SRC_OSC; - mash = BCM2835_CLK_MASH_0; - - if (bcm2835_clk_freq[clk_src] % target_frequency == 0 - && bit_master && frame_master) { - divi = bcm2835_clk_freq[clk_src] / target_frequency; - divf = 0; - } else { - uint64_t dividend; - - if (!dev->bclk_ratio) { - /* - * Overwrite bclk_ratio, because the - * above trick is not needed or can - * not be used. - */ - bclk_ratio = 2 * data_length; - } - - target_frequency = sampling_rate * bclk_ratio; - - clk_src = BCM2835_CLK_SRC_PLLD; - mash = BCM2835_CLK_MASH_1; - - dividend = bcm2835_clk_freq[clk_src]; - dividend <<= BCM2835_CLK_SHIFT; - do_div(dividend, target_frequency); - divi = dividend >> BCM2835_CLK_SHIFT; - divf = dividend & BCM2835_CLK_DIVF_MASK; - } + else + /* otherwise calculate a fitting block ratio */ + bclk_ratio = 2 * data_length; /* Clock should only be set up here if CPU is clock master */ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFM: - /* Set clock divider */ - regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, - BCM2835_CLK_PASSWD - | BCM2835_CLK_DIVI(divi) - | BCM2835_CLK_DIVF(divf)); - - /* Setup clock, but don't start it yet */ - regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, - BCM2835_CLK_PASSWD - | BCM2835_CLK_MASH(mash) - | BCM2835_CLK_SRC(clk_src)); + clk_set_rate(dev->clk, sampling_rate * bclk_ratio); break; default: break; @@ -555,22 +410,15 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, /* Setup the DMA parameters */ regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, - BCM2835_I2S_RXTHR(3) - | BCM2835_I2S_TXTHR(3) - | BCM2835_I2S_DMAEN, - BCM2835_I2S_RXTHR(1) - | BCM2835_I2S_TXTHR(1) - | BCM2835_I2S_DMAEN); + BCM2835_I2S_RXTHR(1) + | BCM2835_I2S_TXTHR(1) + | BCM2835_I2S_DMAEN, 0xffffffff); regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, - BCM2835_I2S_TX_PANIC(0x7f) - | BCM2835_I2S_RX_PANIC(0x7f) - | BCM2835_I2S_TX(0x7f) - | BCM2835_I2S_RX(0x7f), - BCM2835_I2S_TX_PANIC(0x10) - | BCM2835_I2S_RX_PANIC(0x30) - | BCM2835_I2S_TX(0x20) - | BCM2835_I2S_RX(0x20)); + BCM2835_I2S_TX_PANIC(0x10) + | BCM2835_I2S_RX_PANIC(0x30) + | BCM2835_I2S_TX(0x30) + | BCM2835_I2S_RX(0x20), 0xffffffff); /* Clear FIFOs */ bcm2835_i2s_clear_fifos(dev, true, true); @@ -710,7 +558,7 @@ static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = { .trigger = bcm2835_i2s_trigger, .hw_params = bcm2835_i2s_hw_params, .set_fmt = bcm2835_i2s_set_dai_fmt, - .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio + .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio, }; static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai) @@ -770,112 +618,67 @@ static bool bcm2835_i2s_precious_reg(struct device *dev, unsigned int reg) }; } -static bool bcm2835_clk_volatile_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case BCM2835_CLK_PCMCTL_REG: - return true; - default: - return false; - }; -} - -static const struct regmap_config bcm2835_regmap_config[] = { - { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = BCM2835_I2S_GRAY_REG, - .precious_reg = bcm2835_i2s_precious_reg, - .volatile_reg = bcm2835_i2s_volatile_reg, - .cache_type = REGCACHE_RBTREE, - .name = "i2s", - }, - { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = BCM2835_CLK_PCMDIV_REG, - .volatile_reg = bcm2835_clk_volatile_reg, - .cache_type = REGCACHE_RBTREE, - .name = "clk", - }, +static const struct regmap_config bcm2835_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = BCM2835_I2S_GRAY_REG, + .precious_reg = bcm2835_i2s_precious_reg, + .volatile_reg = bcm2835_i2s_volatile_reg, + .cache_type = REGCACHE_RBTREE, }; static const struct snd_soc_component_driver bcm2835_i2s_component = { .name = "bcm2835-i2s-comp", }; -static struct snd_pcm_hardware bcm2835_pcm_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_JOINT_DUPLEX, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - .period_bytes_min = 32, - .period_bytes_max = 64 * PAGE_SIZE, - .periods_min = 2, - .periods_max = 255, - .buffer_bytes_max = 128 * PAGE_SIZE, -}; - -static const struct snd_dmaengine_pcm_config bcm2835_dmaengine_pcm_config = { - .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, - .pcm_hardware = &bcm2835_pcm_hardware, - .prealloc_buffer_size = 256 * PAGE_SIZE, -}; - static int bcm2835_i2s_probe(struct platform_device *pdev) { struct bcm2835_i2s_dev *dev; - int i; int ret; - struct regmap *regmap[2]; - struct resource *mem[2]; + struct resource *mem; + void __iomem *base; const __be32 *addr; - dma_addr_t dma_reg_base; - - addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); - if (!addr) { - dev_err(&pdev->dev, "could not get DMA-register address\n"); - return -ENODEV; - } - dma_reg_base = be32_to_cpup(addr); - - if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) - bcm2835_pcm_hardware.info |= - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID; - - /* Request both ioareas */ - for (i = 0; i <= 1; i++) { - void __iomem *base; - - mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); - base = devm_ioremap_resource(&pdev->dev, mem[i]); - if (IS_ERR(base)) - return PTR_ERR(base); - - regmap[i] = devm_regmap_init_mmio(&pdev->dev, base, - &bcm2835_regmap_config[i]); - if (IS_ERR(regmap[i])) - return PTR_ERR(regmap[i]); - } + dma_addr_t dma_base; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; - dev->i2s_regmap = regmap[0]; - dev->clk_regmap = regmap[1]; + /* get the clock */ + dev->clk_prepared = false; + dev->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(dev->clk)) { + dev_err(&pdev->dev, "could not get clk: %ld\n", + PTR_ERR(dev->clk)); + return PTR_ERR(dev->clk); + } + + /* Request ioarea */ + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(base)) + return PTR_ERR(base); + + dev->i2s_regmap = devm_regmap_init_mmio(&pdev->dev, base, + &bcm2835_regmap_config); + if (IS_ERR(dev->i2s_regmap)) + return PTR_ERR(dev->i2s_regmap); + + /* Set the DMA address - we have to parse DT ourselves */ + addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); + if (!addr) { + dev_err(&pdev->dev, "could not get DMA-register address\n"); + return -EINVAL; + } + dma_base = be32_to_cpup(addr); - /* Set the DMA address */ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = - dma_reg_base + BCM2835_I2S_FIFO_A_REG; + dma_base + BCM2835_I2S_FIFO_A_REG; dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = - dma_reg_base + BCM2835_I2S_FIFO_A_REG; + dma_base + BCM2835_I2S_FIFO_A_REG; /* Set the bus width */ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = @@ -887,6 +690,15 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; + /* + * Set the PACK flag to enable S16_LE support (2 S16_LE values + * packed into 32-bit transfers). + */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].flags = + SND_DMAENGINE_PCM_DAI_FLAG_PACK; + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].flags = + SND_DMAENGINE_PCM_DAI_FLAG_PACK; + /* BCLK ratio - use default */ dev->bclk_ratio = 0; @@ -901,9 +713,7 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) return ret; } - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, - &bcm2835_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_COMPAT); + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); return ret;