From patchwork Wed Mar 10 22:45:07 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 84735 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2AMksUQ006664 for ; Wed, 10 Mar 2010 22:47:34 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3DF5F9F61A; Wed, 10 Mar 2010 14:46:15 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from orsmga101.jf.intel.com (mga06.intel.com [134.134.136.21]) by gabe.freedesktop.org (Postfix) with ESMTP id A06249F5D0 for ; Wed, 10 Mar 2010 14:45:54 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 10 Mar 2010 14:42:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.49,616,1262592000"; d="scan'208";a="499618499" Received: from unknown (HELO localhost.localdomain) ([10.255.13.214]) by orsmga002.jf.intel.com with ESMTP; 10 Mar 2010 14:45:09 -0800 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Wed, 10 Mar 2010 22:45:07 +0000 Message-Id: <1268261124-13653-21-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.7.0 In-Reply-To: <1268261124-13653-1-git-send-email-chris@chris-wilson.co.uk> References: <1268261124-13653-1-git-send-email-chris@chris-wilson.co.uk> Cc: Dave Airlie Subject: [Intel-gfx] [PATCH 20/37] drm: Propagate error from encoder mode set. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 10 Mar 2010 22:47:34 +0000 (UTC) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f2aaf39..b3f369f 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -704,8 +704,11 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, DRM_DEBUG("%s: set mode %s %x\n", drm_get_encoder_name(encoder), mode->name, mode->base.id); + encoder_funcs = encoder->helper_private; - encoder_funcs->mode_set(encoder, mode, adjusted_mode); + ret = encoder_funcs->mode_set(encoder, mode, adjusted_mode); + if (!ret) + goto done; } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index fccf074..0bb6268 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -95,7 +95,7 @@ static bool intel_crt_mode_fixup(struct drm_encoder *encoder, return true; } -static void intel_crt_mode_set(struct drm_encoder *encoder, +static bool intel_crt_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -145,6 +145,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, } I915_WRITE(adpa_reg, adpa); + return true; } static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ef3a0d..e9c0613 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -621,7 +621,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, } } -static void +static bool intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -674,6 +674,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, else dp_priv->DP |= DP_PLL_FREQ_270MHZ; } + + return true; } static void ironlake_edp_backlight_on (struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a4d2606..a0c89f7 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -178,7 +178,7 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, return true; } -static void intel_dvo_mode_set(struct drm_encoder *encoder, +static bool intel_dvo_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -231,6 +231,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, (adjusted_mode->vdisplay << DVO_SRCDIM_VERTICAL_SHIFT)); /*I915_WRITE(DVOB, dvo_val);*/ I915_WRITE(dvo_reg, dvo_val); + + return true; } /** diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a30f8bf..e4a8ab5 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -42,7 +42,7 @@ struct intel_hdmi_priv { bool has_hdmi_sink; }; -static void intel_hdmi_mode_set(struct drm_encoder *encoder, +static bool intel_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -67,6 +67,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, I915_WRITE(hdmi_priv->sdvox_reg, sdvox); POSTING_READ(hdmi_priv->sdvox_reg); + + return true; } static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 14e516f..dafae41 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -580,7 +580,7 @@ static void intel_lvds_commit( struct drm_encoder *encoder) intel_lvds_set_power(dev, true); } -static void intel_lvds_mode_set(struct drm_encoder *encoder, +static bool intel_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -596,7 +596,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, */ if (HAS_PCH_SPLIT(dev)) - return; + return true; /* * Enable automatic panel scaling so that non-native modes fill the @@ -605,6 +605,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, */ I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); + return true; } /* Some lid devices report incorrect lid status, assume they're connected */ diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 04293b5..c5f070e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1132,7 +1132,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, return true; } -static void intel_sdvo_mode_set(struct drm_encoder *encoder, +static bool intel_sdvo_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -1150,7 +1150,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, u8 status; if (!mode) - return; + return false; /* First, set the input mapping for the first input to our controlled * output. This is only correct if we're a single-input device, in @@ -1166,11 +1166,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, &in_out, sizeof(in_out))) status = intel_sdvo_read_response(output, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) - return; + return false; if (sdvo_priv->is_hdmi) { if (!intel_sdvo_set_avi_infoframe(output, mode)) - return; + return false; sdvox |= SDVO_AUDIO_ENABLE; } @@ -1189,19 +1189,19 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, /* Set the output timing to the screen */ if (!intel_sdvo_set_target_output(output, sdvo_priv->controlled_output)) - return; + return false; if (!intel_sdvo_set_output_timing(output, &input_dtd)) - return; + return false; } /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(output, false)) - return; + return false; if (sdvo_priv->is_tv) { if (!intel_sdvo_set_tv_format(output)) - return; + return false; } /* We would like to use intel_sdvo_create_preferred_input_timing() to @@ -1220,7 +1220,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, } #else if (!intel_sdvo_set_input_timing(output, &input_dtd)) - return; + return false; #endif rate = SDVO_CLOCK_RATE_MULT_1X; @@ -1237,7 +1237,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, break; } if (!intel_sdvo_set_clock_rate_mult(output, rate)) - return; + return false; /* Set the SDVO control regs. */ if (IS_I965G(dev)) { @@ -1271,6 +1271,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) sdvox |= SDVO_STALL_SELECT; intel_sdvo_write_sdvox(output, sdvox); + return true; } static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 552ec11..16db9e3 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1113,7 +1113,7 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, return true; } -static void +static bool intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -1134,7 +1134,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, bool burst_ena; if (!tv_mode) - return; /* can't happen (mode_prepare prevents this) */ + return false; /* can't happen (mode_prepare prevents this) */ tv_ctl = I915_READ(TV_CTL); tv_ctl &= TV_CTL_SAVE; @@ -1332,6 +1332,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); I915_WRITE(TV_DAC, 0); I915_WRITE(TV_CTL, tv_ctl); + + return true; } static const struct drm_display_mode reported_modes[] = { diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 1d73b15..6a71991 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -353,7 +353,7 @@ static void nv04_dac_prepare(struct drm_encoder *encoder) } -static void nv04_dac_mode_set(struct drm_encoder *encoder, +static bool nv04_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -388,6 +388,8 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder, NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000); else NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); + + return true; } static void nv04_dac_commit(struct drm_encoder *encoder) diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 483f875..0e03255 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -247,7 +247,7 @@ static void nv04_dfp_prepare(struct drm_encoder *encoder) } -static void nv04_dfp_mode_set(struct drm_encoder *encoder, +static bool nv04_dfp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -401,6 +401,8 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, } regp->fp_margin_color = 0; + + return true; } static void nv04_dfp_commit(struct drm_encoder *encoder) diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 9c63099..76c2324 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c @@ -173,7 +173,7 @@ static void nv04_tv_prepare(struct drm_encoder *encoder) nv04_tv_bind(dev, head, true); } -static void nv04_tv_mode_set(struct drm_encoder *encoder, +static bool nv04_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -196,6 +196,7 @@ static void nv04_tv_mode_set(struct drm_encoder *encoder, regp->tv_vsync_delay = 1; to_encoder_slave(encoder)->slave_funcs->mode_set(encoder, mode, adjusted_mode); + return true; } static void nv04_tv_commit(struct drm_encoder *encoder) diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 21ac6e4..a81b297 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -405,7 +405,7 @@ static void nv17_tv_prepare(struct drm_encoder *encoder) NVWriteRAMDAC(dev, 0, dacclk_off, dacclk); } -static void nv17_tv_mode_set(struct drm_encoder *encoder, +static bool nv17_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *drm_mode, struct drm_display_mode *adjusted_mode) { @@ -518,6 +518,8 @@ static void nv17_tv_mode_set(struct drm_encoder *encoder, regs->fp_margin_color = 0x801080; } + + return true; } static void nv17_tv_commit(struct drm_encoder *encoder) diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index f08f042..baab1fb 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -201,7 +201,7 @@ nv50_dac_commit(struct drm_encoder *encoder) { } -static void +static bool nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -238,11 +238,13 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ret = RING_SPACE(evo, 3); if (ret) { NV_ERROR(dev, "no space while connecting DAC\n"); - return; + return false; } BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); OUT_RING(evo, mode_ctl); OUT_RING(evo, mode_ctl2); + + return true; } static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index c2fff54..022611b 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -184,7 +184,7 @@ nv50_sor_commit(struct drm_encoder *encoder) { } -static void +static bool nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -235,10 +235,12 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ret = RING_SPACE(evo, 2); if (ret) { NV_ERROR(dev, "no space while connecting SOR\n"); - return; + return false; } BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); OUT_RING(evo, mode_ctl); + + return true; } static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index bc926ea..2966467 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1318,7 +1318,7 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) return 1; } -static void +static bool radeon_atom_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -1399,6 +1399,8 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, /* XXX */ if (!ASIC_IS_DCE4(rdev)) r600_hdmi_setmode(encoder, adjusted_mode); + + return true; } static bool diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index cf389ce..f75c226 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -142,7 +142,7 @@ static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) radeon_combios_output_lock(encoder, false); } -static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, +static bool radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -210,6 +210,8 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); else radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); + + return true; } static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, @@ -321,7 +323,7 @@ static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) radeon_combios_output_lock(encoder, false); } -static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, +static bool radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -376,6 +378,8 @@ static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); else radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); + + return true; } static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder, @@ -509,7 +513,7 @@ static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) radeon_combios_output_lock(encoder, true); } -static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, +static bool radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -607,6 +611,8 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); else radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); + + return true; } static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { @@ -676,7 +682,7 @@ static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) radeon_combios_output_lock(encoder, false); } -static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, +static bool radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -743,6 +749,8 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); else radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); + + return true; } static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) @@ -887,7 +895,7 @@ static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) radeon_combios_output_lock(encoder, true); } -static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, +static bool radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -1035,6 +1043,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, else radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); + return true; } static bool r300_legacy_tv_detect(struct drm_encoder *encoder, diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index b29e201..7c91aab 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -76,7 +76,7 @@ struct drm_encoder_helper_funcs { struct drm_display_mode *adjusted_mode); void (*prepare)(struct drm_encoder *encoder); void (*commit)(struct drm_encoder *encoder); - void (*mode_set)(struct drm_encoder *encoder, + bool (*mode_set)(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder);