2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
32 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/socket.h>
38 #include <machine/bus.h>
41 #include <net/if_media.h>
43 #include <dev/dwc/if_dwc.h>
44 #include <dev/dwc/if_dwcvar.h>
45 #include <dev/ofw/ofw_bus.h>
46 #include <dev/ofw/ofw_bus_subr.h>
48 #include <dev/extres/clk/clk.h>
49 #include <dev/extres/hwreset/hwreset.h>
50 #include <dev/extres/regulator/regulator.h>
51 #include <dev/extres/syscon/syscon.h>
53 #include "if_dwc_if.h"
54 #include "syscon_if.h"
56 #define RK3328_GRF_MAC_CON0 0x0900
57 #define MAC_CON0_GMAC2IO_TX_DL_CFG_MASK 0x7F
58 #define MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT 0
59 #define MAC_CON0_GMAC2IO_RX_DL_CFG_MASK 0x7F
60 #define MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT 7
62 #define RK3328_GRF_MAC_CON1 0x0904
63 #define MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA (1 << 0)
64 #define MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA (1 << 1)
65 #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK (3 << 11)
66 #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_125 (0 << 11)
67 #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_25 (3 << 11)
68 #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5 (2 << 11)
69 #define MAC_CON1_GMAC2IO_RMII_MODE_MASK (1 << 9)
70 #define MAC_CON1_GMAC2IO_RMII_MODE (1 << 9)
71 #define MAC_CON1_GMAC2IO_INTF_SEL_MASK (7 << 4)
72 #define MAC_CON1_GMAC2IO_INTF_RMII (4 << 4)
73 #define MAC_CON1_GMAC2IO_INTF_RGMII (1 << 4)
74 #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK (1 << 7)
75 #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 (1 << 7)
76 #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 (0 << 7)
77 #define MAC_CON1_GMAC2IO_MAC_SPEED_MASK (1 << 2)
78 #define MAC_CON1_GMAC2IO_MAC_SPEED_100 (1 << 2)
79 #define MAC_CON1_GMAC2IO_MAC_SPEED_10 (0 << 2)
80 #define RK3328_GRF_MAC_CON2 0x0908
81 #define RK3328_GRF_MACPHY_CON0 0x0B00
82 #define MACPHY_CON0_CLK_50M_MASK (1 << 14)
83 #define MACPHY_CON0_CLK_50M (1 << 14)
84 #define MACPHY_CON0_RMII_MODE_MASK (3 << 6)
85 #define MACPHY_CON0_RMII_MODE (1 << 6)
86 #define RK3328_GRF_MACPHY_CON1 0x0B04
87 #define MACPHY_CON1_RMII_MODE_MASK (1 << 9)
88 #define MACPHY_CON1_RMII_MODE (1 << 9)
89 #define RK3328_GRF_MACPHY_CON2 0x0B08
90 #define RK3328_GRF_MACPHY_CON3 0x0B0C
91 #define RK3328_GRF_MACPHY_STATUS 0x0B10
93 #define RK3399_GRF_SOC_CON5 0xc214
94 #define SOC_CON5_GMAC_CLK_SEL_MASK (3 << 4)
95 #define SOC_CON5_GMAC_CLK_SEL_125 (0 << 4)
96 #define SOC_CON5_GMAC_CLK_SEL_25 (3 << 4)
97 #define SOC_CON5_GMAC_CLK_SEL_2_5 (2 << 4)
98 #define RK3399_GRF_SOC_CON6 0xc218
99 #define SOC_CON6_GMAC_TXCLK_DLY_ENA (1 << 7)
100 #define SOC_CON6_TX_DL_CFG_MASK 0x7F
101 #define SOC_CON6_TX_DL_CFG_SHIFT 0
102 #define SOC_CON6_RX_DL_CFG_MASK 0x7F
103 #define SOC_CON6_GMAC_RXCLK_DLY_ENA (1 << 15)
104 #define SOC_CON6_RX_DL_CFG_SHIFT 8
106 struct if_dwc_rk_softc;
108 typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *);
109 typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int);
110 typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *);
111 typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *);
113 struct if_dwc_rk_ops {
114 if_dwc_rk_set_delaysfn_t set_delays;
115 if_dwc_rk_set_speedfn_t set_speed;
116 if_dwc_rk_set_phy_modefn_t set_phy_mode;
117 if_dwc_rk_phy_powerupfn_t phy_powerup;
120 struct if_dwc_rk_softc {
121 struct dwc_softc base;
128 struct if_dwc_rk_ops *ops;
137 clk_t clk_mac_refout;
142 static void rk3328_set_delays(struct if_dwc_rk_softc *sc);
143 static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed);
144 static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc);
145 static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc);
147 static void rk3399_set_delays(struct if_dwc_rk_softc *sc);
148 static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed);
150 static struct if_dwc_rk_ops rk3288_ops = {
153 static struct if_dwc_rk_ops rk3328_ops = {
154 .set_delays = rk3328_set_delays,
155 .set_speed = rk3328_set_speed,
156 .set_phy_mode = rk3328_set_phy_mode,
157 .phy_powerup = rk3328_phy_powerup,
160 static struct if_dwc_rk_ops rk3399_ops = {
161 .set_delays = rk3399_set_delays,
162 .set_speed = rk3399_set_speed,
165 static struct ofw_compat_data compat_data[] = {
166 {"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops},
167 {"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops},
168 {"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops},
173 rk3328_set_delays(struct if_dwc_rk_softc *sc)
178 if (sc->base.phy_mode != PHY_MODE_RGMII)
181 reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0);
182 tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK);
183 rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK);
185 reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1);
187 device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
188 tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
189 rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
191 device_printf(sc->base.dev, "setting new RK3328 RX/TX delays: %d/%d\n",
192 sc->tx_delay, sc->rx_delay);
195 reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16;
196 reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA);
197 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg);
200 reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
201 MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT);
202 reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
203 MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT);
204 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg);
208 rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed)
212 switch (sc->base.phy_mode) {
217 reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125;
220 reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25;
223 reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5;
226 device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed);
230 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
231 ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg));
236 reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 |
237 MAC_CON1_GMAC2IO_MAC_SPEED_100;
240 reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 |
241 MAC_CON1_GMAC2IO_MAC_SPEED_10;
244 device_printf(sc->base.dev, "unsupported RMII media %u\n", speed);
248 SYSCON_WRITE_4(sc->grf,
249 sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
251 ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16));
259 rk3328_set_phy_mode(struct if_dwc_rk_softc *sc)
262 switch (sc->base.phy_mode) {
264 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
265 ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
266 MAC_CON1_GMAC2IO_INTF_RGMII);
269 SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
270 ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
271 MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE);
277 rk3328_phy_powerup(struct if_dwc_rk_softc *sc)
279 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1,
280 (MACPHY_CON1_RMII_MODE_MASK << 16) |
281 MACPHY_CON1_RMII_MODE);
285 rk3399_set_delays(struct if_dwc_rk_softc *sc)
287 uint32_t reg, tx, rx;
289 if (sc->base.phy_mode != PHY_MODE_RGMII)
292 reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6);
293 tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK);
294 rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK);
297 device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
298 tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
299 rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
301 device_printf(sc->base.dev, "setting new RK3399 RX/TX delays: %d/%d\n",
302 sc->rx_delay, sc->tx_delay);
306 reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) <<
307 SOC_CON6_TX_DL_CFG_SHIFT);
308 reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) <<
309 SOC_CON6_RX_DL_CFG_SHIFT);
310 reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA;
312 SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg);
316 rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed)
323 reg = SOC_CON5_GMAC_CLK_SEL_125;
326 reg = SOC_CON5_GMAC_CLK_SEL_25;
329 reg = SOC_CON5_GMAC_CLK_SEL_2_5;
332 device_printf(sc->base.dev, "unsupported media %u\n", speed);
336 SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5,
337 ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg));
342 if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS)
344 struct if_dwc_rk_softc *sc;
349 rxtx = ((sc->rx_delay << 8) | sc->tx_delay);
351 rv = sysctl_handle_int(oidp, &rxtx, 0, req);
352 if (rv != 0 || req->newptr == NULL)
354 sc->tx_delay = rxtx & 0xff;
355 sc->rx_delay = (rxtx >> 8) & 0xff;
357 if (sc->ops->set_delays)
358 sc->ops->set_delays(sc);
364 if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc)
366 struct sysctl_oid *child;
367 struct sysctl_ctx_list *ctx_list;
369 ctx_list = device_get_sysctl_ctx(sc->base.dev);
370 child = device_get_sysctl_tree(sc->base.dev);
371 SYSCTL_ADD_PROC(ctx_list,
372 SYSCTL_CHILDREN(child), OID_AUTO, "delays",
373 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0,
374 if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)");
380 if_dwc_rk_probe(device_t dev)
383 if (!ofw_bus_status_okay(dev))
385 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
387 device_set_desc(dev, "Rockchip Gigabit Ethernet Controller");
389 return (BUS_PROBE_DEFAULT);
393 if_dwc_rk_init_clocks(device_t dev)
395 struct if_dwc_rk_softc *sc;
398 sc = device_get_softc(dev);
399 error = clk_set_assigned(dev, ofw_bus_get_node(dev));
401 device_printf(dev, "clk_set_assigned failed\n");
406 error = clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->clk_stmmaceth);
408 device_printf(dev, "could not find clock stmmaceth\n");
412 if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
413 device_printf(sc->base.dev, "could not get mac_clk_rx clock\n");
414 sc->mac_clk_rx = NULL;
417 if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) {
418 device_printf(sc->base.dev, "could not get mac_clk_tx clock\n");
419 sc->mac_clk_tx = NULL;
422 if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) {
423 device_printf(sc->base.dev, "could not get aclk_mac clock\n");
427 if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) {
428 device_printf(sc->base.dev, "could not get pclk_mac clock\n");
432 if (sc->base.phy_mode == PHY_MODE_RGMII) {
433 if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) {
434 device_printf(sc->base.dev, "could not get clk_mac_ref clock\n");
435 sc->clk_mac_ref = NULL;
439 if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) {
440 device_printf(sc->base.dev, "could not get clk_mac_refout clock\n");
441 sc->clk_mac_refout = NULL;
444 clk_set_freq(sc->clk_stmmaceth, 50000000, 0);
448 if ((sc->phy_node != 0) && sc->integrated_phy) {
449 if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) {
450 device_printf(sc->base.dev, "could not get PHY clock\n");
455 clk_set_freq(sc->clk_phy, 50000000, 0);
459 if (sc->base.phy_mode == PHY_MODE_RMII) {
461 clk_enable(sc->mac_clk_rx);
463 clk_enable(sc->clk_mac_ref);
464 if (sc->clk_mac_refout)
465 clk_enable(sc->clk_mac_refout);
468 clk_enable(sc->clk_phy);
470 clk_enable(sc->aclk_mac);
472 clk_enable(sc->pclk_mac);
474 clk_enable(sc->mac_clk_tx);
482 if_dwc_rk_init(device_t dev)
484 struct if_dwc_rk_softc *sc;
491 regulator_t phy_supply;
493 sc = device_get_softc(dev);
494 node = ofw_bus_get_node(dev);
495 sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
496 if (OF_hasprop(node, "rockchip,grf") &&
497 syscon_get_by_ofw_property(dev, node,
498 "rockchip,grf", &sc->grf) != 0) {
499 device_printf(dev, "cannot get grf driver handle\n");
503 if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
505 if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
511 if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) {
512 if (strcmp(clock_in_out, "input") == 0)
515 sc->clock_in = false;
516 OF_prop_free(clock_in_out);
519 if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
520 sizeof(phy_handle)) > 0)
521 sc->phy_node = OF_node_from_xref(phy_handle);
524 sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated");
526 if (sc->integrated_phy)
527 device_printf(sc->base.dev, "PHY is integrated\n");
529 if_dwc_rk_init_clocks(dev);
531 if (sc->ops->set_phy_mode)
532 sc->ops->set_phy_mode(sc);
534 if (sc->ops->set_delays)
535 sc->ops->set_delays(sc);
538 * this also sets delays if tunable is defined
540 err = if_dwc_rk_init_sysctl(sc);
544 if (regulator_get_by_ofw_property(sc->base.dev, 0,
545 "phy-supply", &phy_supply) == 0) {
546 if (regulator_enable(phy_supply)) {
547 device_printf(sc->base.dev,
548 "cannot enable 'phy' regulator\n");
552 device_printf(sc->base.dev, "no phy-supply property\n");
555 if (sc->integrated_phy) {
556 if (sc->ops->phy_powerup)
557 sc->ops->phy_powerup(sc);
559 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
560 (MACPHY_CON0_CLK_50M_MASK << 16) |
561 MACPHY_CON0_CLK_50M);
562 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
563 (MACPHY_CON0_RMII_MODE_MASK << 16) |
564 MACPHY_CON0_RMII_MODE);
565 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234);
566 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035);
568 if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset) == 0) {
569 hwreset_assert(phy_reset);
571 hwreset_deassert(phy_reset);
580 if_dwc_rk_mac_type(device_t dev)
583 return (DWC_GMAC_NORMAL_DESC);
587 if_dwc_rk_mii_clk(device_t dev)
590 /* Should be calculated from the clock */
591 return (GMAC_MII_CLK_150_250M_DIV102);
595 if_dwc_rk_set_speed(device_t dev, int speed)
597 struct if_dwc_rk_softc *sc;
599 sc = device_get_softc(dev);
601 if (sc->ops->set_speed)
602 return sc->ops->set_speed(sc, speed);
607 static device_method_t if_dwc_rk_methods[] = {
608 DEVMETHOD(device_probe, if_dwc_rk_probe),
610 DEVMETHOD(if_dwc_init, if_dwc_rk_init),
611 DEVMETHOD(if_dwc_mac_type, if_dwc_rk_mac_type),
612 DEVMETHOD(if_dwc_mii_clk, if_dwc_rk_mii_clk),
613 DEVMETHOD(if_dwc_set_speed, if_dwc_rk_set_speed),
618 static devclass_t dwc_rk_devclass;
620 extern driver_t dwc_driver;
622 DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods,
623 sizeof(struct if_dwc_rk_softc), dwc_driver);
624 DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, dwc_rk_devclass, 0, 0);
625 MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1);