/* * 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 Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include #include #include #include #include #include "skeleton.dtsi" / { compatible = "rockchip,rk3288"; interrupt-parent = <&gic>; aliases { i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; i2c3 = &i2c3; i2c4 = &i2c4; i2c5 = &i2c5; mshc0 = &emmc; mshc1 = &sdmmc; mshc2 = &sdio0; mshc3 = &sdio1; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; serial3 = &uart3; serial4 = &uart4; spi0 = &spi0; spi1 = &spi1; spi2 = &spi2; }; cpus { #address-cells = <1>; #size-cells = <0>; enable-method = "rockchip,rk3066-smp"; rockchip,pmu = <&pmu>; cpu0: cpu@500 { device_type = "cpu"; compatible = "arm,cortex-a12"; reg = <0x500>; resets = <&cru SRST_CORE0>; operating-points = < /* KHz uV */ 1608000 1350000 1512000 1300000 1416000 1200000 1200000 1100000 1008000 1050000 816000 1000000 696000 950000 600000 900000 408000 900000 312000 900000 216000 900000 126000 900000 >; #cooling-cells = <2>; /* min followed by max */ clock-latency = <40000>; clocks = <&cru ARMCLK>; }; cpu@501 { device_type = "cpu"; compatible = "arm,cortex-a12"; reg = <0x501>; resets = <&cru SRST_CORE1>; }; cpu@502 { device_type = "cpu"; compatible = "arm,cortex-a12"; reg = <0x502>; resets = <&cru SRST_CORE2>; }; cpu@503 { device_type = "cpu"; compatible = "arm,cortex-a12"; reg = <0x503>; resets = <&cru SRST_CORE3>; }; }; amba { compatible = "arm,amba-bus"; #address-cells = <1>; #size-cells = <1>; ranges; dmac_peri: dma-controller@ff250000 { compatible = "arm,pl330", "arm,primecell"; reg = <0xff250000 0x4000>; interrupts = , ; #dma-cells = <1>; clocks = <&cru ACLK_DMAC2>; clock-names = "apb_pclk"; }; dmac_bus_ns: dma-controller@ff600000 { compatible = "arm,pl330", "arm,primecell"; reg = <0xff600000 0x4000>; interrupts = , ; #dma-cells = <1>; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; status = "disabled"; }; dmac_bus_s: dma-controller@ffb20000 { compatible = "arm,pl330", "arm,primecell"; reg = <0xffb20000 0x4000>; interrupts = , ; #dma-cells = <1>; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; }; }; xin24m: oscillator { compatible = "fixed-clock"; clock-frequency = <24000000>; clock-output-names = "xin24m"; #clock-cells = <0>; }; timer { compatible = "arm,armv7-timer"; arm,cpu-registers-not-fw-configured; interrupts = , , , ; clock-frequency = <24000000>; }; timer: timer@ff810000 { compatible = "rockchip,rk3288-timer"; reg = <0xff810000 0x20>; interrupts = ; clocks = <&xin24m>, <&cru PCLK_TIMER>; clock-names = "timer", "pclk"; }; display-subsystem { compatible = "rockchip,display-subsystem"; ports = <&vopl_out>, <&vopb_out>; }; sdmmc: dwmmc@ff0c0000 { compatible = "rockchip,rk3288-dw-mshc"; clock-freq-min-max = <400000 150000000>; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; clock-names = "biu", "ciu"; fifo-depth = <0x100>; interrupts = ; reg = <0xff0c0000 0x4000>; status = "disabled"; }; sdio0: dwmmc@ff0d0000 { compatible = "rockchip,rk3288-dw-mshc"; clock-freq-min-max = <400000 150000000>; clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>; clock-names = "biu", "ciu"; fifo-depth = <0x100>; interrupts = ; reg = <0xff0d0000 0x4000>; status = "disabled"; }; sdio1: dwmmc@ff0e0000 { compatible = "rockchip,rk3288-dw-mshc"; clock-freq-min-max = <400000 150000000>; clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>; clock-names = "biu", "ciu"; fifo-depth = <0x100>; interrupts = ; reg = <0xff0e0000 0x4000>; status = "disabled"; }; emmc: dwmmc@ff0f0000 { compatible = "rockchip,rk3288-dw-mshc"; clock-freq-min-max = <400000 150000000>; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; clock-names = "biu", "ciu"; fifo-depth = <0x100>; interrupts = ; reg = <0xff0f0000 0x4000>; status = "disabled"; }; saradc: saradc@ff100000 { compatible = "rockchip,saradc"; reg = <0xff100000 0x100>; interrupts = ; #io-channel-cells = <1>; clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; clock-names = "saradc", "apb_pclk"; status = "disabled"; }; spi0: spi@ff110000 { compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi"; clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac_peri 11>, <&dmac_peri 12>; dma-names = "tx", "rx"; interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>; reg = <0xff110000 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; spi1: spi@ff120000 { compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi"; clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac_peri 13>, <&dmac_peri 14>; dma-names = "tx", "rx"; interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>; reg = <0xff120000 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; spi2: spi@ff130000 { compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi"; clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac_peri 15>, <&dmac_peri 16>; dma-names = "tx", "rx"; interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>; reg = <0xff130000 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; i2c1: i2c@ff140000 { compatible = "rockchip,rk3288-i2c"; reg = <0xff140000 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; clock-names = "i2c"; clocks = <&cru PCLK_I2C1>; pinctrl-names = "default"; pinctrl-0 = <&i2c1_xfer>; status = "disabled"; }; i2c3: i2c@ff150000 { compatible = "rockchip,rk3288-i2c"; reg = <0xff150000 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; clock-names = "i2c"; clocks = <&cru PCLK_I2C3>; pinctrl-names = "default"; pinctrl-0 = <&i2c3_xfer>; status = "disabled"; }; i2c4: i2c@ff160000 { compatible = "rockchip,rk3288-i2c"; reg = <0xff160000 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; clock-names = "i2c"; clocks = <&cru PCLK_I2C4>; pinctrl-names = "default"; pinctrl-0 = <&i2c4_xfer>; status = "disabled"; }; i2c5: i2c@ff170000 { compatible = "rockchip,rk3288-i2c"; reg = <0xff170000 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; clock-names = "i2c"; clocks = <&cru PCLK_I2C5>; pinctrl-names = "default"; pinctrl-0 = <&i2c5_xfer>; status = "disabled"; }; uart0: serial@ff180000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; reg = <0xff180000 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer>; status = "disabled"; }; uart1: serial@ff190000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; reg = <0xff190000 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer>; status = "disabled"; }; uart2: serial@ff690000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; reg = <0xff690000 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&uart2_xfer>; status = "disabled"; }; uart3: serial@ff1b0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; reg = <0xff1b0000 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&uart3_xfer>; status = "disabled"; }; uart4: serial@ff1c0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; reg = <0xff1c0000 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&uart4_xfer>; status = "disabled"; }; thermal-zones { #include "rk3288-thermal.dtsi" }; tsadc: tsadc@ff280000 { compatible = "rockchip,rk3288-tsadc"; reg = <0xff280000 0x100>; interrupts = ; clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; clock-names = "tsadc", "apb_pclk"; resets = <&cru SRST_TSADC>; reset-names = "tsadc-apb"; pinctrl-names = "default"; pinctrl-0 = <&otp_out>; #thermal-sensor-cells = <1>; rockchip,hw-tshut-temp = <95000>; status = "disabled"; }; gmac: ethernet@ff290000 { compatible = "rockchip,rk3288-gmac"; reg = <0xff290000 0x10000>; interrupts = ; interrupt-names = "macirq"; rockchip,grf = <&grf>; clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>, <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>, <&cru ACLK_GMAC>, <&cru PCLK_GMAC>; clock-names = "stmmaceth", "mac_clk_rx", "mac_clk_tx", "clk_mac_ref", "clk_mac_refout", "aclk_mac", "pclk_mac"; status = "disabled"; }; usb_host0_ehci: usb@ff500000 { compatible = "generic-ehci"; reg = <0xff500000 0x100>; interrupts = ; clocks = <&cru HCLK_USBHOST0>; clock-names = "usbhost"; phys = <&usbphy1>; phy-names = "usb"; status = "disabled"; }; /* NOTE: ohci@ff520000 doesn't actually work on hardware */ usb_host1: usb@ff540000 { compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0xff540000 0x40000>; interrupts = ; clocks = <&cru HCLK_USBHOST1>; clock-names = "otg"; phys = <&usbphy2>; phy-names = "usb2-phy"; status = "disabled"; }; usb_otg: usb@ff580000 { compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0xff580000 0x40000>; interrupts = ; clocks = <&cru HCLK_OTG0>; clock-names = "otg"; phys = <&usbphy0>; phy-names = "usb2-phy"; status = "disabled"; }; usb_hsic: usb@ff5c0000 { compatible = "generic-ehci"; reg = <0xff5c0000 0x100>; interrupts = ; clocks = <&cru HCLK_HSIC>; clock-names = "usbhost"; status = "disabled"; }; i2c0: i2c@ff650000 { compatible = "rockchip,rk3288-i2c"; reg = <0xff650000 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; clock-names = "i2c"; clocks = <&cru PCLK_I2C0>; pinctrl-names = "default"; pinctrl-0 = <&i2c0_xfer>; status = "disabled"; }; i2c2: i2c@ff660000 { compatible = "rockchip,rk3288-i2c"; reg = <0xff660000 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; clock-names = "i2c"; clocks = <&cru PCLK_I2C2>; pinctrl-names = "default"; pinctrl-0 = <&i2c2_xfer>; status = "disabled"; }; pwm0: pwm@ff680000 { compatible = "rockchip,rk3288-pwm"; reg = <0xff680000 0x10>; #pwm-cells = <3>; pinctrl-names = "default"; pinctrl-0 = <&pwm0_pin>; clocks = <&cru PCLK_PWM>; clock-names = "pwm"; status = "disabled"; }; pwm1: pwm@ff680010 { compatible = "rockchip,rk3288-pwm"; reg = <0xff680010 0x10>; #pwm-cells
/*
 * Copyright 2009 Ben Skeggs
 * Copyright 2008 Stuart Bennett
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_fbcon.h"

int
nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
	struct nouveau_fbdev *nfbdev = info->par;
	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
	struct nouveau_channel *chan = drm->channel;
	int ret;

	ret = RING_SPACE(chan, 4);
	if (ret)
		return ret;

	BEGIN_NV04(chan, NvSubImageBlit, 0x0300, 3);
	OUT_RING(chan, (region->sy << 16) | region->sx);
	OUT_RING(chan, (region->dy << 16) | region->dx);
	OUT_RING(chan, (region->height << 16) | region->width);
	FIRE_RING(chan);
	return 0;
}

int
nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
	struct nouveau_fbdev *nfbdev = info->par;
	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
	struct nouveau_channel *chan = drm->channel;
	int ret;

	ret = RING_SPACE(chan, 7);
	if (ret)
		return ret;

	BEGIN_NV04(chan, NvSubGdiRect, 0x02fc, 1);
	OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3);
	BEGIN_NV04(chan, NvSubGdiRect, 0x03fc, 1);